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 3f6a566a71
commit d0551db92e
7 changed files with 113 additions and 8 deletions

View File

@ -830,13 +830,13 @@ gfxMacPlatformFontList::RegisteredFontsChangedNotificationCallback(CFNotificatio
return;
}
gfxMacPlatformFontList* fl = static_cast<gfxMacPlatformFontList*>(observer);
// 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
static const char kPrefName[] = "font.internaluseonly.changed";
bool fontInternalChange = Preferences::GetBool(kPrefName, false);
Preferences::SetBool(kPrefName, !fontInternalChange);
fl->ForceGlobalReflow();
}
gfxFontEntry*

View File

@ -9,6 +9,7 @@
#include "prlog.h"
#include "gfxPlatformFontList.h"
#include "gfxUserFontSet.h"
#include "nsUnicharUtils.h"
#include "nsUnicodeRange.h"
@ -303,6 +304,21 @@ gfxPlatformFontList::ResolveFontName(const nsAString& aFontName, nsAString& aRes
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 {
FontListData(nsIAtom *aLangGroup,
const nsACString& aGenericFamily,
@ -797,6 +813,11 @@ gfxPlatformFontList::LoadFontInfo()
}
#endif
if (done) {
mOtherFamilyNamesInitialized = true;
mFaceNamesInitialized = true;
}
return done;
}
@ -820,8 +841,6 @@ gfxPlatformFontList::CleanupLoader()
}
#endif
mOtherFamilyNamesInitialized = true;
mFaceNamesInitialized = true;
gfxFontInfoLoader::CleanupLoader();
}
@ -839,6 +858,15 @@ gfxPlatformFontList::GetPrefsAndStartLoader()
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
static size_t

View File

@ -82,6 +82,8 @@ struct FontListSizes {
uint32_t mCharMapsSize; // memory used for cmap coverage info
};
class gfxUserFontSet;
class gfxPlatformFontList : public gfxFontInfoLoader
{
public:
@ -115,7 +117,7 @@ public:
virtual bool ResolveFontName(const nsAString& aFontName,
nsAString& aResolvedFontName);
void UpdateFontList() { InitFontList(); }
void UpdateFontList();
void ClearPrefFonts() { mPrefFonts.Clear(); }
@ -178,6 +180,15 @@ public:
// remove the cmap from the shared cmap set
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:
class MemoryReporter MOZ_FINAL : public nsIMemoryReporter
{
@ -254,6 +265,9 @@ protected:
// read the loader initialization prefs, and start it
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
static size_t
SizeOfFamilyNameEntryExcludingThis(const nsAString& aKey,
@ -305,6 +319,8 @@ protected:
uint32_t mStartIndex;
uint32_t mIncrement;
uint32_t mNumFamilies;
nsTHashtable<nsPtrHashKey<gfxUserFontSet> > mUserFontSetList;
};
#endif /* GFXPLATFORMFONTLIST_H_ */

View File

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

View File

@ -242,6 +242,9 @@ public:
// increment the generation on font load
void IncrementGeneration();
// rebuild if local rules have been used
void RebuildLocalRules();
class UserFontCache {
public:
// 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, ...);
// helper method for performing the actual userfont set rebuild
virtual void DoRebuildUserFontSet() = 0;
// font families defined by @font-face rules
nsRefPtrHashtable<nsStringHashKey, gfxMixedFontFamily> mFontFamilies;
uint64_t mGeneration;
// true when local names have been looked up, false otherwise
bool mLocalRulesUsed;
static PRLogModuleInfo* GetUserFontsLog();
private:

View File

@ -490,9 +490,24 @@ nsUserFontSet::UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules)
IncrementGeneration();
}
// local rules have been rebuilt, so clear the flag
mLocalRulesUsed = false;
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
nsUserFontSet::InsertRule(nsCSSFontFaceRule* aRule, uint8_t aSheetType,
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
for (uint32_t i = 0; i < aOldRules.Length(); ++i) {
const FontFaceRuleRecord& ruleRec = aOldRules[i];
if (ruleRec.mContainer.mRule == aRule &&
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);
mRules.AppendElement(ruleRec);
aOldRules.RemoveElementAt(i);
@ -983,3 +1010,9 @@ nsUserFontSet::GetPrivateBrowsing()
nsCOMPtr<nsILoadContext> loadContext = ps->GetDocument()->GetLoadContext();
return loadContext && loadContext->UsePrivateBrowsing();
}
void
nsUserFontSet::DoRebuildUserFontSet()
{
mPresContext->RebuildUserFontSet();
}

View File

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