зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1715501 - patch 1 - Track codepoints with no available fonts and replacement-char family separately for each font-visibility level. r=emilio
This does not change existing behavior, but will be required once font visibility is no longer simply a global setting. The data cached in these members depends on the font visibility level, so currently we just flush it if the visibility pref is modified. But in future we may be using multiple levels at the same time (in separate contexts), so we want to maintain separate per-level caches here. Differential Revision: https://phabricator.services.mozilla.com/D124194
This commit is contained in:
Родитель
fa511566f2
Коммит
ffc9bc9fe0
|
@ -519,9 +519,6 @@ bool gfxPlatformFontList::InitFontList() {
|
|||
CancelLoader();
|
||||
|
||||
gfxFontUtils::GetPrefsFontList(kFontSystemWhitelistPref, mEnabledFontsList);
|
||||
|
||||
// Ensure SetVisibilityLevel will clear the mCodepointsWithNoFonts set.
|
||||
mVisibilityLevel = FontVisibility::Unknown;
|
||||
}
|
||||
|
||||
SetVisibilityLevel();
|
||||
|
@ -594,14 +591,16 @@ bool gfxPlatformFontList::InitFontList() {
|
|||
}
|
||||
|
||||
void gfxPlatformFontList::InitializeCodepointsWithNoFonts() {
|
||||
mCodepointsWithNoFonts.reset();
|
||||
mCodepointsWithNoFonts.SetRange(0, 0x1f); // C0 controls
|
||||
mCodepointsWithNoFonts.SetRange(0x7f, 0x9f); // C1 controls
|
||||
mCodepointsWithNoFonts.SetRange(0xE000, 0xF8FF); // PUA
|
||||
mCodepointsWithNoFonts.SetRange(0xF0000, 0x10FFFD); // Supplementary PUA
|
||||
mCodepointsWithNoFonts.SetRange(0xfdd0, 0xfdef); // noncharacters
|
||||
for (auto& bitset : mCodepointsWithNoFonts) {
|
||||
bitset.reset();
|
||||
bitset.SetRange(0, 0x1f); // C0 controls
|
||||
bitset.SetRange(0x7f, 0x9f); // C1 controls
|
||||
bitset.SetRange(0xE000, 0xF8FF); // PUA
|
||||
bitset.SetRange(0xF0000, 0x10FFFD); // Supplementary PUA
|
||||
bitset.SetRange(0xfdd0, 0xfdef); // noncharacters
|
||||
for (unsigned i = 0; i <= 0x100000; i += 0x10000) {
|
||||
mCodepointsWithNoFonts.SetRange(i + 0xfffe, i + 0xffff); // noncharacters
|
||||
bitset.SetRange(i + 0xfffe, i + 0xffff); // noncharacters
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -615,14 +614,7 @@ void gfxPlatformFontList::SetVisibilityLevel() {
|
|||
std::max(int32_t(FontVisibility::Base),
|
||||
StaticPrefs::layout_css_font_visibility_level())));
|
||||
}
|
||||
if (newLevel != mVisibilityLevel) {
|
||||
mVisibilityLevel = newLevel;
|
||||
// (Re-)initialize ranges of characters for which system-wide font search
|
||||
// should be skipped
|
||||
InitializeCodepointsWithNoFonts();
|
||||
// Forget any font family we previously chose for U+FFFD.
|
||||
mReplacementCharFallbackFamily = FontFamily();
|
||||
}
|
||||
}
|
||||
|
||||
void gfxPlatformFontList::FontListChanged() {
|
||||
|
@ -921,7 +913,7 @@ gfxFont* gfxPlatformFontList::SystemFindFontForChar(
|
|||
uint32_t aCh, uint32_t aNextCh, Script aRunScript,
|
||||
eFontPresentation aPresentation, const gfxFontStyle* aStyle,
|
||||
FontVisibility* aVisibility) {
|
||||
MOZ_ASSERT(!mCodepointsWithNoFonts.test(aCh),
|
||||
MOZ_ASSERT(!mCodepointsWithNoFonts[mVisibilityLevel].test(aCh),
|
||||
"don't call for codepoints already known to be unsupported");
|
||||
|
||||
// Try to short-circuit font fallback for U+FFFD, used to represent
|
||||
|
@ -930,25 +922,21 @@ gfxFont* gfxPlatformFontList::SystemFindFontForChar(
|
|||
// etc.
|
||||
if (aCh == 0xFFFD) {
|
||||
gfxFontEntry* fontEntry = nullptr;
|
||||
if (mReplacementCharFallbackFamily.mIsShared &&
|
||||
mReplacementCharFallbackFamily.mShared) {
|
||||
auto& fallbackFamily = mReplacementCharFallbackFamily[mVisibilityLevel];
|
||||
if (fallbackFamily.mIsShared && fallbackFamily.mShared) {
|
||||
fontlist::Face* face =
|
||||
mReplacementCharFallbackFamily.mShared->FindFaceForStyle(
|
||||
SharedFontList(), *aStyle);
|
||||
fallbackFamily.mShared->FindFaceForStyle(SharedFontList(), *aStyle);
|
||||
if (face) {
|
||||
fontEntry =
|
||||
GetOrCreateFontEntry(face, mReplacementCharFallbackFamily.mShared);
|
||||
*aVisibility = mReplacementCharFallbackFamily.mShared->Visibility();
|
||||
fontEntry = GetOrCreateFontEntry(face, fallbackFamily.mShared);
|
||||
*aVisibility = fallbackFamily.mShared->Visibility();
|
||||
}
|
||||
} else if (!mReplacementCharFallbackFamily.mIsShared &&
|
||||
mReplacementCharFallbackFamily.mUnshared) {
|
||||
fontEntry =
|
||||
mReplacementCharFallbackFamily.mUnshared->FindFontForStyle(*aStyle);
|
||||
*aVisibility = mReplacementCharFallbackFamily.mUnshared->Visibility();
|
||||
} else if (!fallbackFamily.mIsShared && fallbackFamily.mUnshared) {
|
||||
fontEntry = fallbackFamily.mUnshared->FindFontForStyle(*aStyle);
|
||||
*aVisibility = fallbackFamily.mUnshared->Visibility();
|
||||
}
|
||||
|
||||
// this should never fail, as we must have found U+FFFD in order to set
|
||||
// mReplacementCharFallbackFamily at all, but better play it safe
|
||||
// mReplacementCharFallbackFamily[...] at all, but better play it safe
|
||||
if (fontEntry && fontEntry->HasCharacter(aCh)) {
|
||||
return fontEntry->FindOrMakeFont(aStyle);
|
||||
}
|
||||
|
@ -1009,13 +997,13 @@ gfxFont* gfxPlatformFontList::SystemFindFontForChar(
|
|||
|
||||
// no match? add to set of non-matching codepoints
|
||||
if (!font) {
|
||||
mCodepointsWithNoFonts.set(aCh);
|
||||
mCodepointsWithNoFonts[mVisibilityLevel].set(aCh);
|
||||
} else {
|
||||
*aVisibility = fallbackFamily.mIsShared
|
||||
? fallbackFamily.mShared->Visibility()
|
||||
: fallbackFamily.mUnshared->Visibility();
|
||||
if (aCh == 0xFFFD) {
|
||||
mReplacementCharFallbackFamily = fallbackFamily;
|
||||
mReplacementCharFallbackFamily[mVisibilityLevel] = fallbackFamily;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2593,8 +2581,9 @@ void gfxPlatformFontList::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
|
|||
}
|
||||
}
|
||||
|
||||
aSizes->mFontListSize +=
|
||||
mCodepointsWithNoFonts.SizeOfExcludingThis(aMallocSizeOf);
|
||||
for (const auto& bitset : mCodepointsWithNoFonts) {
|
||||
aSizes->mFontListSize += bitset.SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
aSizes->mFontListSize +=
|
||||
mFontFamiliesToLoad.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/EnumeratedArray.h"
|
||||
#include "mozilla/FontPropertyTypes.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
|
@ -509,7 +510,7 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
|
|||
mozilla::StyleGenericFontFamily aGenericType);
|
||||
|
||||
bool SkipFontFallbackForChar(uint32_t aCh) const {
|
||||
return mCodepointsWithNoFonts.test(aCh);
|
||||
return mCodepointsWithNoFonts[mVisibilityLevel].test(aCh);
|
||||
}
|
||||
|
||||
// Return whether the given font-family record should be visible to CSS,
|
||||
|
@ -869,13 +870,16 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
|
|||
mLangGroupPrefFonts;
|
||||
mozilla::UniquePtr<PrefFontList> mEmojiPrefFont;
|
||||
|
||||
// when system-wide font lookup fails for a character, cache it to skip future
|
||||
// searches
|
||||
gfxSparseBitSet mCodepointsWithNoFonts;
|
||||
// When system-wide font lookup fails for a character, cache it to skip future
|
||||
// searches. This is an array of bitsets, one for each FontVisibility level.
|
||||
mozilla::EnumeratedArray<FontVisibility, FontVisibility::Count,
|
||||
gfxSparseBitSet>
|
||||
mCodepointsWithNoFonts;
|
||||
|
||||
// the family to use for U+FFFD fallback, to avoid expensive search every time
|
||||
// on pages with lots of problems
|
||||
FontFamily mReplacementCharFallbackFamily;
|
||||
mozilla::EnumeratedArray<FontVisibility, FontVisibility::Count, FontFamily>
|
||||
mReplacementCharFallbackFamily;
|
||||
|
||||
// Sorted array of lowercased family names; use ContainsSorted to test
|
||||
nsTArray<nsCString> mBadUnderlineFamilyNames;
|
||||
|
|
Загрузка…
Ссылка в новой задаче