Skip to content

Commit

Permalink
Bug 1542807 part 4 - Exclude fonts loaded from User and UserAgent ori…
Browse files Browse the repository at this point in the history
…gin sheets from 'document.fonts'. r=jfkthame

Per w3c/csswg-drafts#6126 these were
never intended to be included in the first place so this is just
fixing a bug.  Note that I'm leaving them in the mRuleFaces array
so that the font loading machinery works the same as before.
I'm just excluding them when queried by document.fonts.

Differential Revision: https://phabricator.services.mozilla.com/D111694
  • Loading branch information
Mats Palmgren committed Jun 11, 2021
1 parent 25b6604 commit 8ec6f72
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 5 deletions.
27 changes: 25 additions & 2 deletions layout/style/FontFaceSet.cpp
Expand Up @@ -518,7 +518,11 @@ FontFace* FontFaceSet::GetFontFaceAt(uint32_t aIndex) {
FlushUserFontSet();

if (aIndex < mRuleFaces.Length()) {
return mRuleFaces[aIndex].mFontFace;
auto& entry = mRuleFaces[aIndex];
if (entry.mOrigin.value() != StyleOrigin::Author) {
return nullptr;
}
return entry.mFontFace;
}

aIndex -= mRuleFaces.Length();
Expand All @@ -534,6 +538,20 @@ uint32_t FontFaceSet::Size() {

// Web IDL objects can only expose array index properties up to INT32_MAX.

size_t total = mNonRuleFaces.Length();
for (const auto& entry : mRuleFaces) {
if (entry.mOrigin.value() == StyleOrigin::Author) {
++total;
}
}
return std::min<size_t>(total, INT32_MAX);
}

uint32_t FontFaceSet::SizeIncludingNonAuthorOrigins() {
FlushUserFontSet();

// Web IDL objects can only expose array index properties up to INT32_MAX.

size_t total = mRuleFaces.Length() + mNonRuleFaces.Length();
return std::min<size_t>(total, INT32_MAX);
}
Expand All @@ -551,8 +569,13 @@ already_AddRefed<FontFaceSetIterator> FontFaceSet::Values() {
void FontFaceSet::ForEach(JSContext* aCx, FontFaceSetForEachCallback& aCallback,
JS::Handle<JS::Value> aThisArg, ErrorResult& aRv) {
JS::Rooted<JS::Value> thisArg(aCx, aThisArg);
for (size_t i = 0; i < Size(); i++) {
for (size_t i = 0; i < SizeIncludingNonAuthorOrigins(); i++) {
RefPtr<FontFace> face = GetFontFaceAt(i);
if (!face) {
// The font at index |i| is a non-Author origin font, which we shouldn't
// expose per spec.
continue;
}
aCallback.Call(thisArg, *face, *face, *this, aRv);
if (aRv.Failed()) {
return;
Expand Down
19 changes: 17 additions & 2 deletions layout/style/FontFaceSet.h
Expand Up @@ -158,8 +158,6 @@ class FontFaceSet final : public DOMEventTargetHelper,
NS_IMETHOD StyleSheetLoaded(StyleSheet* aSheet, bool aWasDeferred,
nsresult aStatus) override;

FontFace* GetFontFaceAt(uint32_t aIndex);

void FlushUserFontSet();

static nsPresContext* GetPresContextFor(gfxUserFontSet* aUserFontSet) {
Expand Down Expand Up @@ -188,6 +186,10 @@ class FontFaceSet final : public DOMEventTargetHelper,
void Clear();
bool Delete(FontFace& aFontFace);
bool Has(FontFace& aFontFace);
/**
* This returns the number of Author origin fonts only.
* (see also SizeIncludingNonAuthorOrigins() below)
*/
uint32_t Size();
already_AddRefed<dom::FontFaceSetIterator> Entries();
already_AddRefed<dom::FontFaceSetIterator> Values();
Expand All @@ -200,7 +202,14 @@ class FontFaceSet final : public DOMEventTargetHelper,

void MarkUserFontSetDirty();

/**
* Unlike Size(), this returns the size including non-Author origin fonts.
*/
uint32_t SizeIncludingNonAuthorOrigins();

private:
friend mozilla::dom::FontFaceSetIterator; // needs GetFontFaceAt()

~FontFaceSet();

/**
Expand Down Expand Up @@ -239,6 +248,12 @@ class FontFaceSet final : public DOMEventTargetHelper,
*/
void CheckLoadingFinishedAfterDelay();

/**
* Returns the font at aIndex if it's an Author origin font, or nullptr
* otherwise.
*/
FontFace* GetFontFaceAt(uint32_t aIndex);

/**
* Dispatches a FontFaceSetLoadEvent to this object.
*/
Expand Down
9 changes: 8 additions & 1 deletion layout/style/FontFaceSetIterator.cpp
Expand Up @@ -42,7 +42,14 @@ void FontFaceSetIterator::Next(JSContext* aCx,
return;
}

FontFace* face = mFontFaceSet->GetFontFaceAt(mNextIndex++);
// Skip over non-Author origin fonts (GetFontFaceAt returns nullptr
// for those).
FontFace* face;
while (!(face = mFontFaceSet->GetFontFaceAt(mNextIndex++))) {
if (mNextIndex >= mFontFaceSet->SizeIncludingNonAuthorOrigins()) {
break; // this iterator is done
}
}

if (!face) {
aResult.mValue.setUndefined();
Expand Down

0 comments on commit 8ec6f72

Please sign in to comment.