mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1523181 - Don't implicitly flush the user font set.
Summary: Flushing it at a bad time can cancel loads whose timer / completion handler is in progress, which makes no sense. Reviewers: jfkthame, jwatt, heycam Tags: #secure-revision Bug #: 1523181 Differential Revision: https://phabricator.services.mozilla.com/D17856
This commit is contained in:
parent
38a8cb51e1
commit
0ebf739646
@ -1246,7 +1246,6 @@ Document::Document(const char* aContentType)
|
|||||||
mDidDocumentOpen(false),
|
mDidDocumentOpen(false),
|
||||||
mHasDisplayDocument(false),
|
mHasDisplayDocument(false),
|
||||||
mFontFaceSetDirty(true),
|
mFontFaceSetDirty(true),
|
||||||
mGetUserFontSetCalled(false),
|
|
||||||
mDidFireDOMContentLoaded(true),
|
mDidFireDOMContentLoaded(true),
|
||||||
mHasScrollLinkedEffect(false),
|
mHasScrollLinkedEffect(false),
|
||||||
mFrameRequestCallbacksScheduled(false),
|
mFrameRequestCallbacksScheduled(false),
|
||||||
@ -11601,33 +11600,7 @@ nsAutoSyncOperation::~nsAutoSyncOperation() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxUserFontSet* Document::GetUserFontSet(bool aFlushUserFontSet) {
|
gfxUserFontSet* Document::GetUserFontSet() {
|
||||||
// We want to initialize the user font set lazily the first time the
|
|
||||||
// user asks for it, rather than building it too early and forcing
|
|
||||||
// rule cascade creation. Thus we try to enforce the invariant that
|
|
||||||
// we *never* build the user font set until the first call to
|
|
||||||
// GetUserFontSet. However, once it's been requested, we can't wait
|
|
||||||
// for somebody to call GetUserFontSet in order to rebuild it (see
|
|
||||||
// comments below in MarkUserFontSetDirty for why).
|
|
||||||
#ifdef DEBUG
|
|
||||||
bool userFontSetGottenBefore = mGetUserFontSetCalled;
|
|
||||||
#endif
|
|
||||||
// Set mGetUserFontSetCalled up front, so that FlushUserFontSet will actually
|
|
||||||
// flush.
|
|
||||||
mGetUserFontSetCalled = true;
|
|
||||||
if (mFontFaceSetDirty && aFlushUserFontSet) {
|
|
||||||
// If this assertion fails, and there have actually been changes to
|
|
||||||
// @font-face rules, then we will call StyleChangeReflow in
|
|
||||||
// FlushUserFontSet. If we're in the middle of reflow,
|
|
||||||
// that's a bad thing to do, and the caller was responsible for
|
|
||||||
// flushing first. If we're not (e.g., in frame construction), it's
|
|
||||||
// ok.
|
|
||||||
NS_ASSERTION(!userFontSetGottenBefore || !GetShell() ||
|
|
||||||
!GetShell()->IsReflowLocked(),
|
|
||||||
"FlushUserFontSet should have been called first");
|
|
||||||
FlushUserFontSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mFontFaceSet) {
|
if (!mFontFaceSet) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -11636,12 +11609,6 @@ gfxUserFontSet* Document::GetUserFontSet(bool aFlushUserFontSet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Document::FlushUserFontSet() {
|
void Document::FlushUserFontSet() {
|
||||||
if (!mGetUserFontSetCalled) {
|
|
||||||
return; // No one cares about this font set yet, but we want to be careful
|
|
||||||
// to not unset our mFontFaceSetDirty bit, so when someone really
|
|
||||||
// does we'll create it.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mFontFaceSetDirty) {
|
if (!mFontFaceSetDirty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -11678,22 +11645,20 @@ void Document::FlushUserFontSet() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Document::MarkUserFontSetDirty() {
|
void Document::MarkUserFontSetDirty() {
|
||||||
if (!mGetUserFontSetCalled) {
|
if (mFontFaceSetDirty) {
|
||||||
// We want to lazily build the user font set the first time it's
|
|
||||||
// requested (so we don't force creation of rule cascades too
|
|
||||||
// early), so don't do anything now.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mFontFaceSetDirty = true;
|
mFontFaceSetDirty = true;
|
||||||
|
if (nsIPresShell* shell = GetShell()) {
|
||||||
|
shell->EnsureStyleFlush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FontFaceSet* Document::Fonts() {
|
FontFaceSet* Document::Fonts() {
|
||||||
if (!mFontFaceSet) {
|
if (!mFontFaceSet) {
|
||||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(GetScopeObject());
|
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(GetScopeObject());
|
||||||
mFontFaceSet = new FontFaceSet(window, this);
|
mFontFaceSet = new FontFaceSet(window, this);
|
||||||
GetUserFontSet(); // this will cause the user font set to be
|
FlushUserFontSet();
|
||||||
// created/updated
|
|
||||||
}
|
}
|
||||||
return mFontFaceSet;
|
return mFontFaceSet;
|
||||||
}
|
}
|
||||||
|
@ -3339,7 +3339,7 @@ class Document : public nsINode,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxUserFontSet* GetUserFontSet(bool aFlushUserFontSet = true);
|
gfxUserFontSet* GetUserFontSet();
|
||||||
void FlushUserFontSet();
|
void FlushUserFontSet();
|
||||||
void MarkUserFontSetDirty();
|
void MarkUserFontSetDirty();
|
||||||
mozilla::dom::FontFaceSet* GetFonts() { return mFontFaceSet; }
|
mozilla::dom::FontFaceSet* GetFonts() { return mFontFaceSet; }
|
||||||
@ -4065,9 +4065,6 @@ class Document : public nsINode,
|
|||||||
// Is the current mFontFaceSet valid?
|
// Is the current mFontFaceSet valid?
|
||||||
bool mFontFaceSetDirty : 1;
|
bool mFontFaceSetDirty : 1;
|
||||||
|
|
||||||
// Has GetUserFontSet() been called?
|
|
||||||
bool mGetUserFontSetCalled : 1;
|
|
||||||
|
|
||||||
// True if we have fired the DOMContentLoaded event, or don't plan to fire one
|
// True if we have fired the DOMContentLoaded event, or don't plan to fire one
|
||||||
// (e.g. we're not being parsed at all).
|
// (e.g. we're not being parsed at all).
|
||||||
bool mDidFireDOMContentLoaded : 1;
|
bool mDidFireDOMContentLoaded : 1;
|
||||||
|
@ -3486,6 +3486,8 @@ bool CanvasRenderingContext2D::SetFontInternal(const nsAString& aFont,
|
|||||||
resizedFont.size =
|
resizedFont.size =
|
||||||
(fontStyle->mSize * c->AppUnitsPerDevPixel()) / AppUnitsPerCSSPixel();
|
(fontStyle->mSize * c->AppUnitsPerDevPixel()) / AppUnitsPerCSSPixel();
|
||||||
|
|
||||||
|
c->Document()->FlushUserFontSet();
|
||||||
|
|
||||||
nsFontMetrics::Params params;
|
nsFontMetrics::Params params;
|
||||||
params.language = fontStyle->mLanguage;
|
params.language = fontStyle->mLanguage;
|
||||||
params.explicitLanguage = fontStyle->mExplicitLanguage;
|
params.explicitLanguage = fontStyle->mExplicitLanguage;
|
||||||
@ -4026,6 +4028,7 @@ nsresult CanvasRenderingContext2D::DrawOrMeasureText(
|
|||||||
nsPresContext* presContext = presShell->GetPresContext();
|
nsPresContext* presContext = presShell->GetPresContext();
|
||||||
|
|
||||||
// ensure user font set is up to date
|
// ensure user font set is up to date
|
||||||
|
presContext->Document()->FlushUserFontSet();
|
||||||
currentFontStyle->SetUserFontSet(presContext->GetUserFontSet());
|
currentFontStyle->SetUserFontSet(presContext->GetUserFontSet());
|
||||||
|
|
||||||
if (currentFontStyle->GetStyle()->size == 0.0F) {
|
if (currentFontStyle->GetStyle()->size == 0.0F) {
|
||||||
|
@ -1157,9 +1157,7 @@ void PresShell::Destroy() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mPresContext) {
|
if (mPresContext) {
|
||||||
const bool mayFlushUserFontSet = false;
|
if (gfxUserFontSet* fs = mPresContext->GetUserFontSet()) {
|
||||||
gfxUserFontSet* fs = mPresContext->GetUserFontSet(mayFlushUserFontSet);
|
|
||||||
if (fs) {
|
|
||||||
uint32_t fontCount;
|
uint32_t fontCount;
|
||||||
uint64_t fontSize;
|
uint64_t fontSize;
|
||||||
fs->GetLoadStatistics(fontCount, fontSize);
|
fs->GetLoadStatistics(fontCount, fontSize);
|
||||||
|
@ -9583,8 +9583,7 @@ static nsRect ComputeHTMLReferenceRect(nsIFrame* aFrame,
|
|||||||
/* static */
|
/* static */
|
||||||
already_AddRefed<nsFontMetrics> nsLayoutUtils::GetMetricsFor(
|
already_AddRefed<nsFontMetrics> nsLayoutUtils::GetMetricsFor(
|
||||||
nsPresContext* aPresContext, bool aIsVertical,
|
nsPresContext* aPresContext, bool aIsVertical,
|
||||||
const nsStyleFont* aStyleFont, nscoord aFontSize, bool aUseUserFontSet,
|
const nsStyleFont* aStyleFont, nscoord aFontSize, bool aUseUserFontSet) {
|
||||||
FlushUserFontSet aFlushUserFontSet) {
|
|
||||||
nsFont font = aStyleFont->mFont;
|
nsFont font = aStyleFont->mFont;
|
||||||
font.size = aFontSize;
|
font.size = aFontSize;
|
||||||
gfxFont::Orientation orientation =
|
gfxFont::Orientation orientation =
|
||||||
@ -9593,10 +9592,8 @@ already_AddRefed<nsFontMetrics> nsLayoutUtils::GetMetricsFor(
|
|||||||
params.language = aStyleFont->mLanguage;
|
params.language = aStyleFont->mLanguage;
|
||||||
params.explicitLanguage = aStyleFont->mExplicitLanguage;
|
params.explicitLanguage = aStyleFont->mExplicitLanguage;
|
||||||
params.orientation = orientation;
|
params.orientation = orientation;
|
||||||
params.userFontSet = aUseUserFontSet
|
params.userFontSet =
|
||||||
? aPresContext->GetUserFontSet(aFlushUserFontSet ==
|
aUseUserFontSet ? aPresContext->GetUserFontSet() : nullptr;
|
||||||
FlushUserFontSet::Yes)
|
|
||||||
: nullptr;
|
|
||||||
params.textPerf = aPresContext->GetTextPerfMetrics();
|
params.textPerf = aPresContext->GetTextPerfMetrics();
|
||||||
return aPresContext->DeviceContext()->GetMetricsFor(font, params);
|
return aPresContext->DeviceContext()->GetMetricsFor(font, params);
|
||||||
}
|
}
|
||||||
|
@ -2945,15 +2945,11 @@ class nsLayoutUtils {
|
|||||||
// from preferences.
|
// from preferences.
|
||||||
static uint8_t ControlCharVisibilityDefault();
|
static uint8_t ControlCharVisibilityDefault();
|
||||||
|
|
||||||
enum class FlushUserFontSet {
|
// Callers are responsible to ensure the user-font-set is up-to-date if
|
||||||
Yes,
|
// aUseUserFontSet is true.
|
||||||
No,
|
|
||||||
};
|
|
||||||
|
|
||||||
static already_AddRefed<nsFontMetrics> GetMetricsFor(
|
static already_AddRefed<nsFontMetrics> GetMetricsFor(
|
||||||
nsPresContext* aPresContext, bool aIsVertical,
|
nsPresContext* aPresContext, bool aIsVertical,
|
||||||
const nsStyleFont* aStyleFont, nscoord aFontSize, bool aUseUserFontSet,
|
const nsStyleFont* aStyleFont, nscoord aFontSize, bool aUseUserFontSet);
|
||||||
FlushUserFontSet aFlushUserFontSet);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appropriately add the correct font if we are using DocumentFonts or
|
* Appropriately add the correct font if we are using DocumentFonts or
|
||||||
|
@ -1864,8 +1864,8 @@ bool nsPresContext::HasAuthorSpecifiedRules(const nsIFrame* aFrame,
|
|||||||
aRuleTypeMask, UseDocumentColors());
|
aRuleTypeMask, UseDocumentColors());
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxUserFontSet* nsPresContext::GetUserFontSet(bool aFlushUserFontSet) {
|
gfxUserFontSet* nsPresContext::GetUserFontSet() {
|
||||||
return mDocument->GetUserFontSet(aFlushUserFontSet);
|
return mDocument->GetUserFontSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsPresContext::UserFontSetUpdated(gfxUserFontEntry* aUpdatedFont) {
|
void nsPresContext::UserFontSetUpdated(gfxUserFontEntry* aUpdatedFont) {
|
||||||
|
@ -901,7 +901,7 @@ class nsPresContext : public nsISupports,
|
|||||||
|
|
||||||
bool SuppressingResizeReflow() const { return mSuppressResizeReflow; }
|
bool SuppressingResizeReflow() const { return mSuppressResizeReflow; }
|
||||||
|
|
||||||
gfxUserFontSet* GetUserFontSet(bool aFlushUserFontSet = true);
|
gfxUserFontSet* GetUserFontSet();
|
||||||
|
|
||||||
// Should be called whenever the set of fonts available in the user
|
// Should be called whenever the set of fonts available in the user
|
||||||
// font set changes (e.g., because a new font loads, or because the
|
// font set changes (e.g., because a new font loads, or because the
|
||||||
|
@ -2048,8 +2048,7 @@ GeckoFontMetrics Gecko_GetFontMetrics(RawGeckoPresContextBorrowed aPresContext,
|
|||||||
nsPresContext* presContext = const_cast<nsPresContext*>(aPresContext);
|
nsPresContext* presContext = const_cast<nsPresContext*>(aPresContext);
|
||||||
presContext->SetUsesExChUnits(true);
|
presContext->SetUsesExChUnits(true);
|
||||||
RefPtr<nsFontMetrics> fm = nsLayoutUtils::GetMetricsFor(
|
RefPtr<nsFontMetrics> fm = nsLayoutUtils::GetMetricsFor(
|
||||||
presContext, aIsVertical, aFont, aFontSize, aUseUserFontSet,
|
presContext, aIsVertical, aFont, aFontSize, aUseUserFontSet);
|
||||||
nsLayoutUtils::FlushUserFontSet::No);
|
|
||||||
|
|
||||||
ret.mXSize = fm->XHeight();
|
ret.mXSize = fm->XHeight();
|
||||||
gfxFloat zeroWidth = fm->GetThebesFontGroup()
|
gfxFloat zeroWidth = fm->GetThebesFontGroup()
|
||||||
|
@ -351,9 +351,7 @@ void ServoStyleSet::SetAuthorStyleDisabled(bool aStyleDisabled) {
|
|||||||
already_AddRefed<ComputedStyle> ServoStyleSet::ResolveStyleFor(
|
already_AddRefed<ComputedStyle> ServoStyleSet::ResolveStyleFor(
|
||||||
Element* aElement, LazyComputeBehavior aMayCompute) {
|
Element* aElement, LazyComputeBehavior aMayCompute) {
|
||||||
if (aMayCompute == LazyComputeBehavior::Allow) {
|
if (aMayCompute == LazyComputeBehavior::Allow) {
|
||||||
PreTraverseSync();
|
return ResolveStyleLazily(aElement, CSSPseudoElementType::NotPseudo);
|
||||||
return ResolveStyleLazilyInternal(aElement,
|
|
||||||
CSSPseudoElementType::NotPseudo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResolveServoStyle(*aElement);
|
return ResolveServoStyle(*aElement);
|
||||||
@ -378,6 +376,12 @@ void ServoStyleSet::PreTraverseSync() {
|
|||||||
// is necessary to avoid a data race when updating the cache.
|
// is necessary to avoid a data race when updating the cache.
|
||||||
mozilla::Unused << mDocument->GetRootElement();
|
mozilla::Unused << mDocument->GetRootElement();
|
||||||
|
|
||||||
|
// FIXME(emilio): This shouldn't be needed in theory, the call to the same
|
||||||
|
// function in PresShell should do the work, but as it turns out we
|
||||||
|
// ProcessPendingRestyles() twice, and runnables from frames just constructed
|
||||||
|
// can end up doing editing stuff, which adds stylesheets etc...
|
||||||
|
mDocument->FlushUserFontSet();
|
||||||
|
|
||||||
ResolveMappedAttrDeclarationBlocks();
|
ResolveMappedAttrDeclarationBlocks();
|
||||||
|
|
||||||
nsMediaFeatures::InitSystemMetrics();
|
nsMediaFeatures::InitSystemMetrics();
|
||||||
@ -536,7 +540,6 @@ already_AddRefed<ComputedStyle> ServoStyleSet::ResolveStyleLazily(
|
|||||||
Element* aElement, CSSPseudoElementType aPseudoType,
|
Element* aElement, CSSPseudoElementType aPseudoType,
|
||||||
StyleRuleInclusion aRuleInclusion) {
|
StyleRuleInclusion aRuleInclusion) {
|
||||||
PreTraverseSync();
|
PreTraverseSync();
|
||||||
|
|
||||||
return ResolveStyleLazilyInternal(aElement, aPseudoType, aRuleInclusion);
|
return ResolveStyleLazilyInternal(aElement, aPseudoType, aRuleInclusion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,8 +640,8 @@ void nsDocLoader::DocLoaderIsEmpty(bool aFlushLayout) {
|
|||||||
// since the reflow is what starts font loads.
|
// since the reflow is what starts font loads.
|
||||||
mozilla::FlushType flushType = mozilla::FlushType::Style;
|
mozilla::FlushType flushType = mozilla::FlushType::Style;
|
||||||
// Be safe in case this presshell is in teardown now
|
// Be safe in case this presshell is in teardown now
|
||||||
nsPresContext* presContext = doc->GetPresContext();
|
doc->FlushUserFontSet();
|
||||||
if (presContext && presContext->GetUserFontSet()) {
|
if (doc->GetUserFontSet()) {
|
||||||
flushType = mozilla::FlushType::Layout;
|
flushType = mozilla::FlushType::Layout;
|
||||||
}
|
}
|
||||||
mDontFlushLayout = mIsFlushingLayout = true;
|
mDontFlushLayout = mIsFlushingLayout = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user