diff --git a/layout/style/nsFontFaceLoader.cpp b/layout/style/nsFontFaceLoader.cpp index d561b04cca3..eecd0518245 100644 --- a/layout/style/nsFontFaceLoader.cpp +++ b/layout/style/nsFontFaceLoader.cpp @@ -413,54 +413,39 @@ static PLDHashOperator DetachFontEntries(const nsAString& aKey, return PL_DHASH_NEXT; } -static PLDHashOperator RemoveIfEmpty(const nsAString& aKey, - nsRefPtr& aFamily, - void* aUserArg) -{ - return aFamily->GetFontList().Length() ? PL_DHASH_NEXT : PL_DHASH_REMOVE; -} - bool nsUserFontSet::UpdateRules(const nsTArray& aRules) { bool modified = false; - // The @font-face rules that make up the user font set have changed, - // so we need to update the set. However, we want to preserve existing - // font entries wherever possible, so that we don't discard and then - // re-download resources in the (common) case where at least some of the - // same rules are still present. + // destroy any current loaders, as the entries they refer to + // may be about to get replaced + if (mLoaders.Count() > 0) { + modified = true; // trigger reflow so that any necessary downloads + // will be reinitiated + } + mLoaders.EnumerateEntries(DestroyIterator, nullptr); nsTArray oldRules; mRules.SwapElements(oldRules); - // Remove faces from the font family records; we need to re-insert them - // because we might end up with faces in a different order even if they're - // the same font entries as before. (The order can affect font selection - // where multiple faces match the requested style, perhaps with overlapping - // unicode-range coverage.) + // destroy the font family records; we need to re-create them + // because we might end up with faces in a different order, + // even if they're the same font entries as before mFontFamilies.Enumerate(DetachFontEntries, nullptr); + mFontFamilies.Clear(); for (uint32_t i = 0, i_end = aRules.Length(); i < i_end; ++i) { - // Insert each rule into our list, migrating old font entries if possible + // insert each rule into our list, migrating old font entries if possible // rather than creating new ones; set modified to true if we detect - // that rule ordering has changed, or if a new entry is created. + // that rule ordering has changed, or if a new entry is created InsertRule(aRules[i].mRule, aRules[i].mSheetType, oldRules, modified); } - // Remove any residual families that have no font entries (i.e., they were - // not defined at all by the updated set of @font-face rules). - mFontFamilies.Enumerate(RemoveIfEmpty, nullptr); - - // If any rules are left in the old list, note that the set has changed - // (even if the new set was built entirely by migrating old font entries). + // if any rules are left in the old list, note that the set has changed if (oldRules.Length() > 0) { modified = true; - // Any in-progress loaders for obsolete rules should be cancelled, - // as the resource being downloaded will no longer be required. - // We need to explicitly remove any loaders here, otherwise the loaders - // will keep their "orphaned" font entries alive until they complete, - // even after the oldRules array is deleted. + // any in-progress loaders for obsolete rules should be cancelled size_t count = oldRules.Length(); for (size_t i = 0; i < count; ++i) { gfxFontEntry *fe = oldRules[i].mFontEntry;