mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 1163877 - Part 3: Update state on, and reflow documents for, all FontFaceSets that contain a FontFace whose user font entry updated. r=jdaggett
This commit is contained in:
parent
a049f1a983
commit
4872fb60dc
@ -413,7 +413,13 @@ gfxUserFontEntry::LoadNextSrc()
|
||||
mWeight,
|
||||
mStretch,
|
||||
mItalic);
|
||||
mFontSet->SetLocalRulesUsed();
|
||||
nsTArray<gfxUserFontSet*> fontSets;
|
||||
GetUserFontSets(fontSets);
|
||||
for (gfxUserFontSet* fontSet : fontSets) {
|
||||
// We need to note on each gfxUserFontSet that contains the user
|
||||
// font entry that we used a local() rule.
|
||||
fontSet->SetLocalRulesUsed();
|
||||
}
|
||||
if (fe) {
|
||||
LOG(("userfonts (%p) [src %d] loaded local: (%s) for (%s) gen: %8.8x\n",
|
||||
mFontSet, mSrcIndex,
|
||||
@ -680,6 +686,16 @@ gfxUserFontEntry::Load()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gfxUserFontEntry::IncrementGeneration()
|
||||
{
|
||||
nsTArray<gfxUserFontSet*> fontSets;
|
||||
GetUserFontSets(fontSets);
|
||||
for (gfxUserFontSet* fontSet : fontSets) {
|
||||
fontSet->IncrementGeneration();
|
||||
}
|
||||
}
|
||||
|
||||
// This is called when a font download finishes.
|
||||
// Ownership of aFontData passes in here, and the font set must
|
||||
// ensure that it is eventually deleted via free().
|
||||
@ -698,7 +714,7 @@ gfxUserFontEntry::FontDataDownloadComplete(const uint8_t* aFontData,
|
||||
aFontData = nullptr;
|
||||
|
||||
if (loaded) {
|
||||
mFontSet->IncrementGeneration();
|
||||
IncrementGeneration();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -720,10 +736,17 @@ gfxUserFontEntry::FontDataDownloadComplete(const uint8_t* aFontData,
|
||||
// even if loading failed, we need to bump the font-set generation
|
||||
// and return true in order to trigger reflow, so that fallback
|
||||
// will be used where the text was "masked" by the pending download
|
||||
mFontSet->IncrementGeneration();
|
||||
IncrementGeneration();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
gfxUserFontEntry::GetUserFontSets(nsTArray<gfxUserFontSet*>& aResult)
|
||||
{
|
||||
aResult.Clear();
|
||||
aResult.AppendElement(mFontSet);
|
||||
}
|
||||
|
||||
gfxUserFontSet::gfxUserFontSet()
|
||||
: mFontFamilies(4), mLocalRulesUsed(false)
|
||||
{
|
||||
|
@ -625,6 +625,15 @@ protected:
|
||||
uint32_t aMetaOrigLen,
|
||||
uint8_t aCompression);
|
||||
|
||||
// Clears and then adds to aResult all of the user font sets that this user
|
||||
// font entry has been added to. This will at least include mFontSet, the
|
||||
// owner of this user font entry.
|
||||
virtual void GetUserFontSets(nsTArray<gfxUserFontSet*>& aResult);
|
||||
|
||||
// Calls IncrementGeneration() on all user font sets that contain this
|
||||
// user font entry.
|
||||
void IncrementGeneration();
|
||||
|
||||
// general load state
|
||||
UserFontLoadState mUserFontLoadState;
|
||||
|
||||
@ -650,7 +659,7 @@ protected:
|
||||
// This field is managed by the nsFontFaceLoader. In the destructor and Cancel()
|
||||
// methods of nsFontFaceLoader this reference is nulled out.
|
||||
nsFontFaceLoader* MOZ_NON_OWNING_REF mLoader; // current loader for this entry, if any
|
||||
gfxUserFontSet* mFontSet; // font-set to which the userfont entry belongs
|
||||
gfxUserFontSet* mFontSet; // font-set which owns this userfont entry
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
};
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "mozilla/dom/FontFace.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "mozilla/dom/FontFaceBinding.h"
|
||||
#include "mozilla/dom/FontFaceSet.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
@ -737,5 +738,25 @@ FontFace::Entry::SetLoadState(UserFontLoadState aLoadState)
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
FontFace::Entry::GetUserFontSets(nsTArray<gfxUserFontSet*>& aResult)
|
||||
{
|
||||
aResult.Clear();
|
||||
|
||||
for (FontFace* f : mFontFaces) {
|
||||
if (f->mInFontFaceSet) {
|
||||
aResult.AppendElement(f->mFontFaceSet->GetUserFontSet());
|
||||
}
|
||||
for (FontFaceSet* s : f->mOtherFontFaceSets) {
|
||||
aResult.AppendElement(s->GetUserFontSet());
|
||||
}
|
||||
}
|
||||
|
||||
// Remove duplicates.
|
||||
aResult.Sort();
|
||||
auto it = std::unique(aResult.begin(), aResult.end());
|
||||
aResult.TruncateLength(it - aResult.begin());
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -53,6 +53,7 @@ public:
|
||||
aUnicodeRanges) {}
|
||||
|
||||
virtual void SetLoadState(UserFontLoadState aLoadState) override;
|
||||
virtual void GetUserFontSets(nsTArray<gfxUserFontSet*>& aResult) override;
|
||||
const nsAutoTArray<FontFace*,1>& GetFontFaces() { return mFontFaces; }
|
||||
|
||||
protected:
|
||||
|
@ -149,6 +149,12 @@ public:
|
||||
|
||||
void FlushUserFontSet();
|
||||
|
||||
static nsPresContext* GetPresContextFor(gfxUserFontSet* aUserFontSet)
|
||||
{
|
||||
FontFaceSet* set = static_cast<UserFontSet*>(aUserFontSet)->mFontFaceSet;
|
||||
return set ? set->GetPresContext() : nullptr;
|
||||
}
|
||||
|
||||
// -- Web IDL --------------------------------------------------------------
|
||||
|
||||
IMPL_EVENT_HANDLER(loading)
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "mozilla/gfx/2D.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
#define LOG(args) MOZ_LOG(gfxUserFontSet::GetUserFontsLog(), mozilla::LogLevel::Debug, args)
|
||||
#define LOG_ENABLED() MOZ_LOG_TEST(gfxUserFontSet::GetUserFontsLog(), \
|
||||
@ -31,7 +32,7 @@ using namespace mozilla;
|
||||
|
||||
nsFontFaceLoader::nsFontFaceLoader(gfxUserFontEntry* aUserFontEntry,
|
||||
nsIURI* aFontURI,
|
||||
mozilla::dom::FontFaceSet* aFontFaceSet,
|
||||
FontFaceSet* aFontFaceSet,
|
||||
nsIChannel* aChannel)
|
||||
: mUserFontEntry(aUserFontEntry),
|
||||
mFontURI(aFontURI),
|
||||
@ -73,7 +74,7 @@ nsFontFaceLoader::StartedLoading(nsIStreamLoader* aStreamLoader)
|
||||
mStreamLoader = aStreamLoader;
|
||||
}
|
||||
|
||||
void
|
||||
/* static */ void
|
||||
nsFontFaceLoader::LoadTimerCallback(nsITimer* aTimer, void* aClosure)
|
||||
{
|
||||
nsFontFaceLoader* loader = static_cast<nsFontFaceLoader*>(aClosure);
|
||||
@ -117,11 +118,16 @@ nsFontFaceLoader::LoadTimerCallback(nsITimer* aTimer, void* aClosure)
|
||||
// font will be used in the meantime, and tell the context to refresh.
|
||||
if (updateUserFontSet) {
|
||||
ufe->mFontDataLoadingState = gfxUserFontEntry::LOADING_SLOWLY;
|
||||
nsPresContext* ctx = loader->mFontFaceSet->GetPresContext();
|
||||
if (ctx) {
|
||||
loader->mFontFaceSet->IncrementGeneration();
|
||||
ctx->UserFontSetUpdated(loader->GetUserFontEntry());
|
||||
LOG(("userfonts (%p) timeout reflow\n", loader));
|
||||
nsTArray<gfxUserFontSet*> fontSets;
|
||||
ufe->GetUserFontSets(fontSets);
|
||||
for (gfxUserFontSet* fontSet : fontSets) {
|
||||
nsPresContext* ctx = FontFaceSet::GetPresContextFor(fontSet);
|
||||
if (ctx) {
|
||||
fontSet->IncrementGeneration();
|
||||
ctx->UserFontSetUpdated(ufe);
|
||||
LOG(("userfonts (%p) timeout reflow for pres context %p\n",
|
||||
loader, ctx));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -179,16 +185,22 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader,
|
||||
// This is called even in the case of a failed download (HTTP 404, etc),
|
||||
// as there may still be data to be freed (e.g. an error page),
|
||||
// and we need to load the next source.
|
||||
nsPresContext* ctx = mFontFaceSet->GetPresContext();
|
||||
bool fontUpdate =
|
||||
mUserFontEntry->FontDataDownloadComplete(aString, aStringLen, aStatus);
|
||||
|
||||
// when new font loaded, need to reflow
|
||||
if (fontUpdate && ctx) {
|
||||
// Update layout for the presence of the new font. Since this is
|
||||
// asynchronous, reflows will coalesce.
|
||||
ctx->UserFontSetUpdated(mUserFontEntry);
|
||||
LOG(("userfonts (%p) reflow\n", this));
|
||||
if (fontUpdate) {
|
||||
nsTArray<gfxUserFontSet*> fontSets;
|
||||
mUserFontEntry->GetUserFontSets(fontSets);
|
||||
for (gfxUserFontSet* fontSet : fontSets) {
|
||||
nsPresContext* ctx = FontFaceSet::GetPresContextFor(fontSet);
|
||||
if (ctx) {
|
||||
// Update layout for the presence of the new font. Since this is
|
||||
// asynchronous, reflows will coalesce.
|
||||
ctx->UserFontSetUpdated(mUserFontEntry);
|
||||
LOG(("userfonts (%p) reflow for pres context %p\n", this, ctx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// done with font set
|
||||
@ -214,7 +226,7 @@ nsFontFaceLoader::Cancel()
|
||||
mChannel->Cancel(NS_BINDING_ABORTED);
|
||||
}
|
||||
|
||||
nsresult
|
||||
/* static */ nsresult
|
||||
nsFontFaceLoader::CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
|
||||
nsIURI* aTargetURI,
|
||||
nsISupports* aContext)
|
||||
|
Loading…
Reference in New Issue
Block a user