Bug 1716045 - Unify font-family storage. r=mats,jfkthame

This changes font-family storage to reuse the rust types, removing a
bunch of code while at it. This allows us to, for example, use a single
static font family for -moz-bullet and clone it, rather than creating a
lot of expensive copies.

Differential Revision: https://phabricator.services.mozilla.com/D118011
This commit is contained in:
Emilio Cobos Álvarez 2021-06-18 19:35:50 +00:00
parent 94ce0999ad
commit fb069248c0
42 changed files with 518 additions and 984 deletions

View File

@ -4084,9 +4084,11 @@ gfxFontGroup* CanvasRenderingContext2D::GetCurrentFontStyle() {
int32_t perDevPixel, perCSSPixel;
GetAppUnitsValues(&perDevPixel, &perCSSPixel);
gfxFloat devToCssSize = gfxFloat(perDevPixel) / gfxFloat(perCSSPixel);
const auto* sans =
Servo_FontFamily_Generic(StyleGenericFontFamily::SansSerif);
fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(
FontFamilyList(StyleGenericFontFamily::SansSerif), &style, language,
explicitLanguage, tp, fontStats, nullptr, devToCssSize);
sans->families, &style, language, explicitLanguage, tp, fontStats,
nullptr, devToCssSize);
if (fontGroup) {
CurrentState().font = kDefaultFontStyle;
} else {

View File

@ -924,15 +924,19 @@ nsresult ContentEventHandler::GenerateFlatFontRanges(
if (aFontRanges.IsEmpty()) {
MOZ_ASSERT(baseOffset == 0);
FontRange* fontRange = AppendFontRange(aFontRanges, baseOffset);
nsIFrame* frame = content->GetPrimaryFrame();
if (frame) {
if (nsIFrame* frame = content->GetPrimaryFrame()) {
const nsFont& font = frame->GetParent()->StyleFont()->mFont;
const FontFamilyList& fontList = font.fontlist;
const FontFamilyName& fontName =
fontList.IsEmpty() ? FontFamilyName(fontList.GetDefaultFontType())
: fontList.GetFontlist()->mNames[0];
const StyleFontFamilyList& fontList = font.family.families;
MOZ_ASSERT(!fontList.list.IsEmpty(), "Empty font family?");
const StyleSingleFontFamily* fontName =
fontList.list.IsEmpty() ? nullptr : &fontList.list.AsSpan()[0];
nsAutoCString name;
fontName.AppendToString(name, false);
if (fontName) {
fontName->AppendToString(name, false);
} else if (fontList.fallback != StyleGenericFontFamily::None) {
StyleSingleFontFamily::Generic(fontList.fallback)
.AppendToString(name, false);
}
AppendUTF8toUTF16(name, fontRange->mFontName);
fontRange->mFontSize = frame->PresContext()->CSSPixelsToDevPixels(
font.size.ToCSSPixels() *

View File

@ -19,26 +19,27 @@
using namespace mozilla;
nsFont::nsFont(const FontFamilyList& aFontlist, mozilla::Length aSize)
: fontlist(aFontlist), size(aSize) {}
nsFont::nsFont(const StyleFontFamily& aFamily, mozilla::Length aSize)
: family(aFamily), size(aSize) {}
nsFont::nsFont(StyleGenericFontFamily aGenericType, mozilla::Length aSize)
: fontlist(aGenericType), size(aSize) {}
: family(*Servo_FontFamily_Generic(aGenericType)), size(aSize) {}
nsFont::nsFont(const nsFont& aOther) = default;
nsFont::~nsFont() = default;
nsFont& nsFont::operator=(const nsFont&) = default;
bool nsFont::Equals(const nsFont& aOther) const {
return CalcDifference(aOther) == MaxDifference::eNone;
}
nsFont::MaxDifference nsFont::CalcDifference(const nsFont& aOther) const {
if ((style != aOther.style) || (systemFont != aOther.systemFont) ||
(weight != aOther.weight) || (stretch != aOther.stretch) ||
(size != aOther.size) || (sizeAdjust != aOther.sizeAdjust) ||
(fontlist != aOther.fontlist) || (kerning != aOther.kerning) ||
(opticalSizing != aOther.opticalSizing) ||
if ((style != aOther.style) || (weight != aOther.weight) ||
(stretch != aOther.stretch) || (size != aOther.size) ||
(sizeAdjust != aOther.sizeAdjust) || (family != aOther.family) ||
(kerning != aOther.kerning) || (opticalSizing != aOther.opticalSizing) ||
(synthesis != aOther.synthesis) ||
(fontFeatureSettings != aOther.fontFeatureSettings) ||
(fontVariationSettings != aOther.fontVariationSettings) ||
@ -61,8 +62,6 @@ nsFont::MaxDifference nsFont::CalcDifference(const nsFont& aOther) const {
return MaxDifference::eNone;
}
nsFont& nsFont::operator=(const nsFont& aOther) = default;
// mapping from bitflag to font feature tag/value pair
//
// these need to be kept in sync with the constants listed

View File

@ -8,7 +8,6 @@
#define nsFont_h___
#include <cstdint>
#include "gfxFontFamilyList.h"
#include "gfxFontConstants.h" // for NS_FONT_KERNING_AUTO, etc
#include "gfxFontVariations.h"
#include "mozilla/FontPropertyTypes.h"
@ -26,8 +25,7 @@ struct nsFont final {
typedef mozilla::FontWeight FontWeight;
// List of font families, either named or generic.
// This contains a RefPtr and a uint32_t field.
mozilla::FontFamilyList fontlist;
mozilla::StyleFontFamily family;
// Font features from CSS font-feature-settings
CopyableTArray<gfxFontFeature> fontFeatureSettings;
@ -87,12 +85,8 @@ struct nsFont final {
// Synthesis setting, controls use of fake bolding/italics
uint8_t synthesis = NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE;
// Force this font to not be considered a 'generic' font, even if
// the name is the same as a CSS generic font family.
bool systemFont = false;
// initialize the font with a fontlist
nsFont(const mozilla::FontFamilyList& aFontlist, mozilla::Length aSize);
nsFont(const mozilla::StyleFontFamily&, mozilla::Length aSize);
// initialize the font with a single generic
nsFont(mozilla::StyleGenericFontFamily, mozilla::Length aSize);

View File

@ -118,12 +118,12 @@ nsFontMetrics::nsFontMetrics(const nsFont& aFont, const Params& aParams,
mTextRunRTL(false),
mVertical(false),
mTextOrientation(mozilla::StyleTextOrientation::Mixed) {
gfxFontStyle style(aFont.style, aFont.weight, aFont.stretch,
gfxFontStyle style(
aFont.style, aFont.weight, aFont.stretch,
gfxFloat(aFont.size.ToAppUnits()) / mP2A, aFont.sizeAdjust,
aFont.systemFont, mDeviceContext->IsPrinterContext(),
aFont.family.is_system_font, mDeviceContext->IsPrinterContext(),
aFont.synthesis & NS_FONT_SYNTHESIS_WEIGHT,
aFont.synthesis & NS_FONT_SYNTHESIS_STYLE,
aFont.languageOverride);
aFont.synthesis & NS_FONT_SYNTHESIS_STYLE, aFont.languageOverride);
aFont.AddFontFeaturesToStyle(&style, mOrientation == eVertical);
style.featureValueLookup = aParams.featureValueLookup;
@ -132,8 +132,8 @@ nsFontMetrics::nsFontMetrics(const nsFont& aFont, const Params& aParams,
gfxFloat devToCssSize = gfxFloat(mP2A) / gfxFloat(AppUnitsPerCSSPixel());
mFontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(
aFont.fontlist, &style, mLanguage, mExplicitLanguage, aParams.textPerf,
aParams.fontStats, aParams.userFontSet, devToCssSize);
aFont.family.families, &style, mLanguage, mExplicitLanguage,
aParams.textPerf, aParams.fontStats, aParams.userFontSet, devToCssSize);
}
nsFontMetrics::~nsFontMetrics() {

View File

@ -8,7 +8,6 @@
#include "gfxFcPlatformFontList.h"
#include "gfxFont.h"
#include "gfxFontConstants.h"
#include "gfxFontFamilyList.h"
#include "gfxFT2Utils.h"
#include "gfxPlatform.h"
#include "mozilla/ArrayUtils.h"
@ -2053,7 +2052,7 @@ bool gfxFcPlatformFontList::FindAndAddFamilies(
// fontconfig generics? use fontconfig to determine the family for lang
if (isDeprecatedGeneric ||
mozilla::FontFamilyName::Convert(familyName).IsGeneric()) {
mozilla::StyleSingleFontFamily::Parse(familyName).IsGeneric()) {
PrefFontList* prefFonts = FindGenericFamilies(familyName, aLanguage);
if (prefFonts && !prefFonts->IsEmpty()) {
aOutput->AppendElements(*prefFonts);

View File

@ -4152,29 +4152,3 @@ bool gfxFont::TryGetMathTable() {
return !!mMathTable;
}
/* static */
void SharedFontList::Initialize() {
sEmpty = new SharedFontList();
for (auto i : IntegerRange(ArrayLength(sSingleGenerics))) {
auto type = static_cast<StyleGenericFontFamily>(i);
if (type != StyleGenericFontFamily::None) {
sSingleGenerics[i] = new SharedFontList(type);
}
}
}
/* static */
void SharedFontList::Shutdown() {
sEmpty = nullptr;
for (auto& sharedFontList : sSingleGenerics) {
sharedFontList = nullptr;
}
}
StaticRefPtr<SharedFontList> SharedFontList::sEmpty;
StaticRefPtr<SharedFontList>
SharedFontList::sSingleGenerics[size_t(StyleGenericFontFamily::MozEmoji)];

View File

@ -1,344 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_FONT_FAMILY_LIST_H
#define GFX_FONT_FAMILY_LIST_H
#include "nsAtom.h"
#include "nsDebug.h"
#include "nsISupportsImpl.h"
#include "nsReadableUtils.h"
#include "nsString.h"
#include "nsUnicharUtils.h"
#include "nsTArray.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/NotNull.h"
#include "mozilla/ServoStyleConsts.h"
#include "mozilla/StaticPtr.h"
namespace mozilla {
/**
* font family name, an Atom for the name if not a generic and
* a font type indicated named family or which generic family
*/
struct FontFamilyName final {
using Syntax = StyleFontFamilyNameSyntax;
FontFamilyName() = delete;
// named font family - e.g. Helvetica
explicit FontFamilyName(nsAtom* aFamilyName, Syntax aSyntax)
: mName(aFamilyName), mSyntax(aSyntax) {}
explicit FontFamilyName(const nsACString& aFamilyName, Syntax aSyntax)
: mName(NS_Atomize(aFamilyName)), mSyntax(aSyntax) {}
// generic font family - e.g. sans-serif
explicit FontFamilyName(StyleGenericFontFamily aGeneric)
: mGeneric(aGeneric) {
MOZ_ASSERT(mGeneric != StyleGenericFontFamily::None);
}
FontFamilyName(const FontFamilyName&) = default;
bool IsNamed() const { return !!mName; }
bool IsGeneric() const { return !IsNamed(); }
bool IsQuoted() const { return mSyntax == StyleFontFamilyNameSyntax::Quoted; }
void AppendToString(nsACString& aFamilyList, bool aQuotes = true) const {
if (IsNamed()) {
if (mSyntax == Syntax::Identifiers) {
return aFamilyList.Append(nsAtomCString(mName));
}
if (aQuotes) {
aFamilyList.Append('"');
}
aFamilyList.Append(nsAtomCString(mName));
if (aQuotes) {
aFamilyList.Append('"');
}
return;
}
switch (mGeneric) {
case StyleGenericFontFamily::None:
case StyleGenericFontFamily::MozEmoji:
MOZ_FALLTHROUGH_ASSERT("Should never appear in a font-family name!");
case StyleGenericFontFamily::Serif:
return aFamilyList.AppendLiteral("serif");
case StyleGenericFontFamily::SansSerif:
return aFamilyList.AppendLiteral("sans-serif");
case StyleGenericFontFamily::Monospace:
return aFamilyList.AppendLiteral("monospace");
case StyleGenericFontFamily::Cursive:
return aFamilyList.AppendLiteral("cursive");
case StyleGenericFontFamily::Fantasy:
return aFamilyList.AppendLiteral("fantasy");
}
MOZ_ASSERT_UNREACHABLE("Unknown generic font-family!");
return aFamilyList.AppendLiteral("serif");
}
// helper method that converts generic names to the right enum value
static FontFamilyName Convert(const nsACString& aFamilyOrGenericName) {
// should only be passed a single font - not entirely correct, a family
// *could* have a comma in it but in practice never does so
// for debug purposes this is fine
NS_ASSERTION(aFamilyOrGenericName.FindChar(',') == -1,
"Convert method should only be passed a single family name");
auto genericType = StyleGenericFontFamily::None;
if (aFamilyOrGenericName.LowerCaseEqualsLiteral("serif")) {
genericType = StyleGenericFontFamily::Serif;
} else if (aFamilyOrGenericName.LowerCaseEqualsLiteral("sans-serif")) {
genericType = StyleGenericFontFamily::SansSerif;
} else if (aFamilyOrGenericName.LowerCaseEqualsLiteral("monospace") ||
aFamilyOrGenericName.LowerCaseEqualsLiteral("-moz-fixed")) {
genericType = StyleGenericFontFamily::Monospace;
} else if (aFamilyOrGenericName.LowerCaseEqualsLiteral("cursive")) {
genericType = StyleGenericFontFamily::Cursive;
} else if (aFamilyOrGenericName.LowerCaseEqualsLiteral("fantasy")) {
genericType = StyleGenericFontFamily::Fantasy;
} else {
return FontFamilyName(aFamilyOrGenericName, Syntax::Identifiers);
}
return FontFamilyName(genericType);
}
bool IsNamedFamily(const nsAString& aFamilyName) const {
if (!IsNamed()) {
return false;
}
nsDependentAtomString name{mName};
return name.Equals(aFamilyName, nsCaseInsensitiveStringComparator);
}
RefPtr<nsAtom> mName; // null if mGeneric != Default
StyleFontFamilyNameSyntax mSyntax = StyleFontFamilyNameSyntax::Quoted;
StyleGenericFontFamily mGeneric = StyleGenericFontFamily::None;
};
inline bool operator==(const FontFamilyName& a, const FontFamilyName& b) {
return a.mName == b.mName && a.mSyntax == b.mSyntax &&
a.mGeneric == b.mGeneric;
}
/**
* A refcounted array of FontFamilyNames. We use this to store the specified
* and computed value of the font-family property.
*
* TODO(heycam): It might better to define this type (and FontFamilyList and
* FontFamilyName) in Rust.
*/
class SharedFontList {
using Syntax = StyleFontFamilyNameSyntax;
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedFontList);
SharedFontList() = default;
explicit SharedFontList(StyleGenericFontFamily aGenericType)
: mNames{FontFamilyName(aGenericType)} {}
SharedFontList(nsAtom* aFamilyName, Syntax aSyntax)
: mNames{FontFamilyName(aFamilyName, aSyntax)} {}
SharedFontList(const nsACString& aFamilyName, Syntax aSyntax)
: mNames{FontFamilyName(aFamilyName, aSyntax)} {}
explicit SharedFontList(nsTArray<FontFamilyName>&& aNames)
: mNames(std::move(aNames)) {}
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
size_t n = 0;
n += aMallocSizeOf(this);
n += mNames.ShallowSizeOfExcludingThis(aMallocSizeOf);
return n;
}
size_t SizeOfIncludingThisIfUnshared(MallocSizeOf aMallocSizeOf) const {
size_t n = 0;
if (mRefCnt.get() == 1) {
n += SizeOfIncludingThis(aMallocSizeOf);
}
return n;
}
const nsTArray<FontFamilyName> mNames{};
static void Initialize();
static void Shutdown();
static StaticRefPtr<SharedFontList> sEmpty;
static StaticRefPtr<SharedFontList>
sSingleGenerics[size_t(StyleGenericFontFamily::MozEmoji)];
private:
~SharedFontList() = default;
};
/**
* font family list, array of font families and a default font type.
* font family names are either named strings or generics. the default
* font type is used to preserve the variable font fallback behavior
*/
class FontFamilyList {
using Syntax = StyleFontFamilyNameSyntax;
public:
FontFamilyList() = default;
explicit FontFamilyList(StyleGenericFontFamily aGenericType)
: mFontlist(MakeNotNull<SharedFontList*>(aGenericType)) {}
FontFamilyList(nsAtom* aFamilyName, Syntax aSyntax)
: mFontlist(MakeNotNull<SharedFontList*>(aFamilyName, aSyntax)) {}
FontFamilyList(const nsACString& aFamilyName, Syntax aSyntax)
: mFontlist(MakeNotNull<SharedFontList*>(aFamilyName, aSyntax)) {}
explicit FontFamilyList(nsTArray<FontFamilyName>&& aNames)
: mFontlist(MakeNotNull<SharedFontList*>(std::move(aNames))) {}
FontFamilyList(const FontFamilyList& aOther) = default;
explicit FontFamilyList(NotNull<SharedFontList*> aFontList)
: mFontlist(aFontList) {}
void SetFontlist(nsTArray<FontFamilyName>&& aNames) {
mFontlist = MakeNotNull<SharedFontList*>(std::move(aNames));
}
void SetFontlist(NotNull<SharedFontList*> aFontlist) {
mFontlist = aFontlist;
}
uint32_t Length() const { return mFontlist->mNames.Length(); }
bool IsEmpty() const { return mFontlist->mNames.IsEmpty(); }
NotNull<SharedFontList*> GetFontlist() const { return mFontlist; }
bool Equals(const FontFamilyList& aFontlist) const {
return (mFontlist == aFontlist.mFontlist ||
mFontlist->mNames == aFontlist.mFontlist->mNames) &&
mDefaultFontType == aFontlist.mDefaultFontType;
}
bool HasDefaultGeneric() const {
if (mDefaultFontType == StyleGenericFontFamily::None) {
return false;
}
for (const FontFamilyName& name : mFontlist->mNames) {
if (name.mGeneric == mDefaultFontType) {
return true;
}
}
return false;
}
// Find the first generic (but ignoring cursive and fantasy, as they are
// rarely configured in any useful way) in the list.
// If found, move it to the start and return true; else return false.
bool PrioritizeFirstGeneric() {
uint32_t len = mFontlist->mNames.Length();
for (uint32_t i = 0; i < len; i++) {
const FontFamilyName name = mFontlist->mNames[i];
if (name.IsGeneric()) {
if (name.mGeneric == StyleGenericFontFamily::Cursive ||
name.mGeneric == StyleGenericFontFamily::Fantasy) {
continue;
}
if (i > 0) {
nsTArray<FontFamilyName> names;
names.AppendElements(mFontlist->mNames);
names.RemoveElementAt(i);
names.InsertElementAt(0, name);
SetFontlist(std::move(names));
}
return true;
}
}
return false;
}
void PrependGeneric(StyleGenericFontFamily aGeneric) {
nsTArray<FontFamilyName> names;
names.AppendElements(mFontlist->mNames);
names.InsertElementAt(0, FontFamilyName(aGeneric));
SetFontlist(std::move(names));
}
void ToString(nsACString& aFamilyList, bool aQuotes = true,
bool aIncludeDefault = false) const {
aFamilyList =
StringJoin(","_ns, mFontlist->mNames,
[aQuotes](nsACString& dst, const FontFamilyName& name) {
name.AppendToString(dst, aQuotes);
});
if (aIncludeDefault && mDefaultFontType != StyleGenericFontFamily::None) {
if (!aFamilyList.IsEmpty()) {
aFamilyList.Append(',');
}
if (mDefaultFontType == StyleGenericFontFamily::Serif) {
aFamilyList.AppendLiteral("serif");
} else {
aFamilyList.AppendLiteral("sans-serif");
}
}
}
// searches for a specific non-generic name, case-insensitive comparison
bool Contains(const nsAString& aFamilyName) const {
for (const FontFamilyName& name : mFontlist->mNames) {
if (name.IsNamedFamily(aFamilyName)) {
return true;
}
}
return false;
}
StyleGenericFontFamily GetDefaultFontType() const { return mDefaultFontType; }
void SetDefaultFontType(StyleGenericFontFamily aType) {
NS_ASSERTION(aType == StyleGenericFontFamily::None ||
aType == StyleGenericFontFamily::Serif ||
aType == StyleGenericFontFamily::SansSerif,
"default font type must be either serif or sans-serif");
mDefaultFontType = aType;
}
// memory reporting
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
size_t n = 0;
n += mFontlist->SizeOfIncludingThisIfUnshared(aMallocSizeOf);
return n;
}
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
protected:
NotNull<RefPtr<SharedFontList>> mFontlist{
WrapNotNull(SharedFontList::sEmpty.get())};
StyleGenericFontFamily mDefaultFontType =
StyleGenericFontFamily::None; // or serif, or sans-serif
};
inline bool operator==(const FontFamilyList& a, const FontFamilyList& b) {
return a.Equals(b);
}
inline bool operator!=(const FontFamilyList& a, const FontFamilyList& b) {
return !a.Equals(b);
}
} // namespace mozilla
#endif /* GFX_FONT_FAMILY_LIST_H */

View File

@ -1894,7 +1894,7 @@ bool gfxPlatform::IsFontFormatSupported(uint32_t aFormatFlags) {
}
gfxFontGroup* gfxPlatform::CreateFontGroup(
const FontFamilyList& aFontFamilyList, const gfxFontStyle* aStyle,
const StyleFontFamilyList& aFontFamilyList, const gfxFontStyle* aStyle,
nsAtom* aLanguage, bool aExplicitLanguage, gfxTextPerfMetrics* aTextPerf,
FontMatchingStats* aFontMatchingStats, gfxUserFontSet* aUserFontSet,
gfxFloat aDevToCssSize) const {

View File

@ -43,7 +43,7 @@ struct FontMatchingStats;
typedef struct FT_LibraryRec_* FT_Library;
namespace mozilla {
class FontFamilyList;
struct StyleFontFamilyList;
class LogModule;
namespace layers {
class FrameStats;
@ -400,13 +400,11 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
/**
* Create a gfxFontGroup based on the given family list and style.
*/
gfxFontGroup* CreateFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
const gfxFontStyle* aStyle, nsAtom* aLanguage,
bool aExplicitLanguage,
gfxTextPerfMetrics* aTextPerf,
FontMatchingStats* aFontMatchingStats,
gfxUserFontSet* aUserFontSet,
gfxFloat aDevToCssSize) const;
gfxFontGroup* CreateFontGroup(
const mozilla::StyleFontFamilyList& aFontFamilyList,
const gfxFontStyle* aStyle, nsAtom* aLanguage, bool aExplicitLanguage,
gfxTextPerfMetrics* aTextPerf, FontMatchingStats* aFontMatchingStats,
gfxUserFontSet* aUserFontSet, gfxFloat aDevToCssSize) const;
/**
* Look up a local platform font using the full font face name.

View File

@ -17,7 +17,6 @@
#include "gfxFont.h"
#include "gfxFontConstants.h"
#include "gfxPlatform.h"
#include "gfxFontFamilyList.h"
#include "SharedFontList.h"
#include "nsIMemoryReporter.h"

View File

@ -1831,7 +1831,7 @@ void gfxTextRun::Dump(FILE* out) {
}
#endif
gfxFontGroup::gfxFontGroup(const FontFamilyList& aFontFamilyList,
gfxFontGroup::gfxFontGroup(const StyleFontFamilyList& aFontFamilyList,
const gfxFontStyle* aStyle, nsAtom* aLanguage,
bool aExplicitLanguage,
gfxTextPerfMetrics* aTextPerf,
@ -1868,18 +1868,18 @@ void gfxFontGroup::BuildFontList() {
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
// lookup fonts in the fontlist
for (const FontFamilyName& name : mFamilyList.GetFontlist()->mNames) {
if (name.IsNamed()) {
if (name.mName) {
AddPlatformFont(nsAtomCString(name.mName), name.IsQuoted(), fonts);
} else {
MOZ_ASSERT_UNREACHABLE("broken FontFamilyName, no atom!");
}
for (const StyleSingleFontFamily& name : mFamilyList.list.AsSpan()) {
if (name.IsFamilyName()) {
const auto& familyName = name.AsFamilyName();
AddPlatformFont(nsAtomCString(familyName.name.AsAtom()),
familyName.syntax == StyleFontFamilyNameSyntax::Quoted,
fonts);
} else {
MOZ_ASSERT(name.IsGeneric());
if (mFirstGeneric == StyleGenericFontFamily::None) {
mFirstGeneric = name.mGeneric;
mFirstGeneric = name.AsGeneric();
}
pfl->AddGenericFonts(name.mGeneric, mLanguage, fonts);
pfl->AddGenericFonts(name.AsGeneric(), mLanguage, fonts);
if (mTextPerf) {
mTextPerf->current.genericLookups++;
}
@ -1920,10 +1920,10 @@ void gfxFontGroup::BuildFontList() {
}
}
// if necessary, append default generic onto the end
if (mFamilyList.GetDefaultFontType() != StyleGenericFontFamily::None &&
!mFamilyList.HasDefaultGeneric()) {
pfl->AddGenericFonts(mFamilyList.GetDefaultFontType(), mLanguage, fonts);
// if necessary, append fallback generic onto the end
if (mFamilyList.fallback != StyleGenericFontFamily::None &&
!mFamilyList.ContainsFallback()) {
pfl->AddGenericFonts(mFamilyList.fallback, mLanguage, fonts);
if (mTextPerf) {
mTextPerf->current.genericLookups++;
}
@ -2113,6 +2113,14 @@ bool gfxFontGroup::FamilyFace::EqualsUserFont(
return false;
}
static nsAutoCString FamilyListToString(
const StyleFontFamilyList& aFamilyList) {
return StringJoin(","_ns, aFamilyList.list.AsSpan(),
[](nsACString& dst, const StyleSingleFontFamily& name) {
name.AppendToString(dst);
});
}
gfxFont* gfxFontGroup::GetDefaultFont() {
if (mDefaultFont) {
return mDefaultFont.get();
@ -2230,10 +2238,8 @@ gfxFont* gfxFontGroup::GetDefaultFont() {
gfxCriticalError() << fontInitInfo.get();
char msg[256]; // CHECK buffer length if revising message below
nsAutoCString familiesString;
mFamilyList.ToString(familiesString);
SprintfLiteral(msg, "unable to find a usable font (%.220s)",
familiesString.get());
FamilyListToString(mFamilyList).get());
MOZ_CRASH_UNSAFE(msg);
}
@ -2548,8 +2554,6 @@ void gfxFontGroup::InitTextRun(DrawTarget* aDrawTarget, gfxTextRun* aTextRun,
if (MOZ_UNLIKELY(MOZ_LOG_TEST(log, LogLevel::Warning))) {
nsAutoCString lang;
mLanguage->ToUTF8String(lang);
nsAutoCString families;
mFamilyList.ToString(families);
nsAutoCString str((const char*)aString, aLength);
nsAutoString styleString;
nsStyleUtil::AppendFontSlantStyle(mStyle.style, styleString);
@ -2558,11 +2562,11 @@ void gfxFontGroup::InitTextRun(DrawTarget* aDrawTarget, gfxTextRun* aTextRun,
("(%s) fontgroup: [%s] default: %s lang: %s script: %d "
"len %d weight: %g stretch: %g%% style: %s size: %6.2f %zu-byte "
"TEXTRUN [%s] ENDTEXTRUN\n",
(mStyle.systemFont ? "textrunui" : "textrun"), families.get(),
(mFamilyList.GetDefaultFontType() == StyleGenericFontFamily::Serif
(mStyle.systemFont ? "textrunui" : "textrun"),
FamilyListToString(mFamilyList).get(),
(mFamilyList.fallback == StyleGenericFontFamily::Serif
? "serif"
: (mFamilyList.GetDefaultFontType() ==
StyleGenericFontFamily::SansSerif
: (mFamilyList.fallback == StyleGenericFontFamily::SansSerif
? "sans-serif"
: "none")),
lang.get(), static_cast<int>(Script::LATIN), aLength,
@ -2595,8 +2599,6 @@ void gfxFontGroup::InitTextRun(DrawTarget* aDrawTarget, gfxTextRun* aTextRun,
if (MOZ_UNLIKELY(MOZ_LOG_TEST(log, LogLevel::Warning))) {
nsAutoCString lang;
mLanguage->ToUTF8String(lang);
nsAutoCString families;
mFamilyList.ToString(families);
nsAutoString styleString;
nsStyleUtil::AppendFontSlantStyle(mStyle.style, styleString);
uint32_t runLen = runLimit - runStart;
@ -2605,12 +2607,11 @@ void gfxFontGroup::InitTextRun(DrawTarget* aDrawTarget, gfxTextRun* aTextRun,
("(%s) fontgroup: [%s] default: %s lang: %s script: %d "
"len %d weight: %g stretch: %g%% style: %s size: %6.2f "
"%zu-byte TEXTRUN [%s] ENDTEXTRUN\n",
(mStyle.systemFont ? "textrunui" : "textrun"), families.get(),
(mFamilyList.GetDefaultFontType() ==
StyleGenericFontFamily::Serif
(mStyle.systemFont ? "textrunui" : "textrun"),
FamilyListToString(mFamilyList).get(),
(mFamilyList.fallback == StyleGenericFontFamily::Serif
? "serif"
: (mFamilyList.GetDefaultFontType() ==
StyleGenericFontFamily::SansSerif
: (mFamilyList.fallback == StyleGenericFontFamily::SansSerif
? "sans-serif"
: "none")),
lang.get(), static_cast<int>(runScript), runLen,
@ -3558,8 +3559,6 @@ void gfxFontGroup::ComputeRanges(nsTArray<TextRange>& aRanges, const T* aString,
if (MOZ_UNLIKELY(MOZ_LOG_TEST(log, LogLevel::Debug))) {
nsAutoCString lang;
mLanguage->ToUTF8String(lang);
nsAutoCString families;
mFamilyList.ToString(families);
// collect the font matched for each range
nsAutoCString fontMatches;
@ -3589,11 +3588,11 @@ void gfxFontGroup::ComputeRanges(nsTArray<TextRange>& aRanges, const T* aString,
MOZ_LOG(log, LogLevel::Debug,
("(%s-fontmatching) fontgroup: [%s] default: %s lang: %s script: %d"
"%s\n",
(mStyle.systemFont ? "textrunui" : "textrun"), families.get(),
(mFamilyList.GetDefaultFontType() == StyleGenericFontFamily::Serif
(mStyle.systemFont ? "textrunui" : "textrun"),
FamilyListToString(mFamilyList).get(),
(mFamilyList.fallback == StyleGenericFontFamily::Serif
? "serif"
: (mFamilyList.GetDefaultFontType() ==
StyleGenericFontFamily::SansSerif
: (mFamilyList.fallback == StyleGenericFontFamily::SansSerif
? "sans-serif"
: "none")),
lang.get(), static_cast<int>(aRunScript), fontMatches.get()));

View File

@ -932,7 +932,7 @@ class gfxFontGroup final : public gfxTextRunFactory {
static void
Shutdown(); // platform must call this to release the languageAtomService
gfxFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
gfxFontGroup(const mozilla::StyleFontFamilyList& aFontFamilyList,
const gfxFontStyle* aStyle, nsAtom* aLanguage,
bool aExplicitLanguage, gfxTextPerfMetrics* aTextPerf,
FontMatchingStats* aFontMatchingStats,
@ -1373,7 +1373,7 @@ class gfxFontGroup final : public gfxTextRunFactory {
// List of font families, either named or generic.
// Generic names map to system pref fonts based on language.
mozilla::FontFamilyList mFamilyList;
mozilla::StyleFontFamilyList mFamilyList;
// Fontlist containing a font entry for each family found. gfxFont objects
// are created as needed and userfont loads are initiated when needed.

View File

@ -31,7 +31,6 @@ EXPORTS += [
"gfxFont.h",
"gfxFontConstants.h",
"gfxFontEntry.h",
"gfxFontFamilyList.h",
"gfxFontFeatures.h",
"gfxFontInfoLoader.h",
"gfxFontPrefLangList.h",

View File

@ -154,7 +154,6 @@ function treatAsSafeArgument(entry, varName, csuName)
// to be a way to indicate which params are out parameters, either using
// an attribute or a naming convention.
["Gecko_CopyAnimationNames", "aDest", null],
["Gecko_CopyFontFamilyFrom", "dst", null],
["Gecko_SetAnimationName", "aStyleAnimation", null],
["Gecko_SetCounterStyleToName", "aPtr", null],
["Gecko_SetCounterStyleToSymbols", "aPtr", null],
@ -182,7 +181,6 @@ function treatAsSafeArgument(entry, varName, csuName)
["Gecko_CopyClipPathValueFrom", "aDst", null],
["Gecko_DestroyClipPath", "aClip", null],
["Gecko_ResetFilters", "effects", null],
["Gecko_CopyFiltersFrom", "aDest", null],
[/Gecko_CSSValue_Set/, "aCSSValue", null],
["Gecko_CSSValue_Drop", "aCSSValue", null],
["Gecko_CSSFontFaceRule_GetCssText", "aResult", null],

View File

@ -129,7 +129,7 @@ void LangGroupFontPrefs::Initialize(nsStaticAtom* aLangGroupAtom) {
nsFont* font = fontTypes[eType];
// set the default variable font (the other fonts are seen as 'generic'
// Set the default variable font (the other fonts are seen as 'generic'
// fonts in GFX and will be queried there when hunting for alternative
// fonts)
if (eType == eDefaultFont_Variable) {
@ -138,32 +138,19 @@ void LangGroupFontPrefs::Initialize(nsStaticAtom* aLangGroupAtom) {
nsAutoCString value;
Preferences::GetCString(pref.get(), value);
if (!value.IsEmpty()) {
FontFamilyName defaultVariableName = FontFamilyName::Convert(value);
StyleGenericFontFamily defaultType = defaultVariableName.mGeneric;
NS_ASSERTION(defaultType == StyleGenericFontFamily::Serif ||
defaultType == StyleGenericFontFamily::SansSerif,
"default type must be serif or sans-serif");
mDefaultVariableFont.fontlist = FontFamilyList();
mDefaultVariableFont.fontlist.SetDefaultFontType(defaultType);
// We create mDefaultVariableFont.fontlist with defaultType as the
// fallback font, and not as part of the font list proper. This way,
// it can be overwritten should there be a language change.
} else {
if (value.IsEmpty()) {
MAKE_FONT_PREF_KEY(pref, "font.default.", langGroup);
Preferences::GetCString(pref.get(), value);
}
if (!value.IsEmpty()) {
FontFamilyName defaultVariableName = FontFamilyName::Convert(value);
StyleGenericFontFamily defaultType = defaultVariableName.mGeneric;
auto defaultVariableName = StyleSingleFontFamily::Parse(value);
auto defaultType = defaultVariableName.IsGeneric()
? defaultVariableName.AsGeneric()
: StyleGenericFontFamily::None;
NS_ASSERTION(defaultType == StyleGenericFontFamily::Serif ||
defaultType == StyleGenericFontFamily::SansSerif,
"default type must be serif or sans-serif");
mDefaultVariableFont.fontlist = FontFamilyList();
mDefaultVariableFont.fontlist.SetDefaultFontType(defaultType);
// We create mDefaultVariableFont.fontlist with defaultType as the
// (fallback) font, and not as part of the font list proper. This way,
// it can be overwritten should there be a language change.
}
mDefaultVariableFont.family.families.fallback = defaultType;
}
} else {
if (eType != eDefaultFont_Monospace) {

View File

@ -27,9 +27,9 @@ struct LangGroupFontPrefs {
mDefaultMonospaceFont(StyleGenericFontFamily::Monospace, {0}),
mDefaultCursiveFont(StyleGenericFontFamily::Cursive, {0}),
mDefaultFantasyFont(StyleGenericFontFamily::Fantasy, {0}) {
mDefaultVariableFont.fontlist.SetDefaultFontType(
StyleGenericFontFamily::Serif);
// We create mDefaultVariableFont.fontlist with defaultType as the
mDefaultVariableFont.family.families.fallback =
StyleGenericFontFamily::Serif;
// We create mDefaultVariableFont.family with defaultType as the
// fallback font, and not as part of the font list proper. This way,
// it can be overwritten should there be a language change.
}

View File

@ -9710,12 +9710,10 @@ void nsLayoutUtils::ComputeSystemFont(nsFont* aSystemFont,
return;
}
systemFontName.Trim("\"'");
aSystemFont->fontlist =
FontFamilyList(NS_ConvertUTF16toUTF8(systemFontName),
StyleFontFamilyNameSyntax::Identifiers);
aSystemFont->fontlist.SetDefaultFontType(StyleGenericFontFamily::None);
NS_ConvertUTF16toUTF8 nameu8(systemFontName);
Servo_FontFamily_ForSystemFont(&nameu8, &aSystemFont->family);
aSystemFont->style = fontStyle.style;
aSystemFont->systemFont = fontStyle.systemFont;
aSystemFont->family.is_system_font = fontStyle.systemFont;
aSystemFont->weight = fontStyle.weight;
aSystemFont->stretch = fontStyle.stretch;
aSystemFont->size = Length::FromPixels(fontStyle.size);

View File

@ -176,7 +176,6 @@ nsresult nsLayoutStatics::Initialize() {
nsCellMap::Init();
mozilla::SharedFontList::Initialize();
StaticPresData::Init();
nsCSSRendering::Init();
css::ImageLoader::Init();
@ -378,7 +377,6 @@ void nsLayoutStatics::Shutdown() {
HTMLInputElement::DestroyUploadLastDir();
nsLayoutUtils::Shutdown();
mozilla::SharedFontList::Shutdown();
nsHyphenationManager::Shutdown();
nsDOMMutationObserver::Shutdown();

View File

@ -58,14 +58,7 @@ static const float kLargeOpFactor = float(M_SQRT2);
static const float kIntegralFactor = 2.0;
static void NormalizeDefaultFont(nsFont& aFont, float aFontSizeInflation) {
if (aFont.fontlist.GetDefaultFontType() != StyleGenericFontFamily::None) {
nsTArray<FontFamilyName> names;
names.AppendElements(aFont.fontlist.GetFontlist()->mNames);
names.AppendElement(FontFamilyName(aFont.fontlist.GetDefaultFontType()));
aFont.fontlist.SetFontlist(std::move(names));
aFont.fontlist.SetDefaultFontType(StyleGenericFontFamily::None);
}
Servo_FontFamilyList_Normalize(&aFont.family.families);
aFont.size.ScaleBy(aFontSizeInflation);
}
@ -89,8 +82,7 @@ class nsGlyphTable {
public:
virtual ~nsGlyphTable() = default;
virtual const FontFamilyName& FontNameFor(
const nsGlyphCode& aGlyphCode) const = 0;
virtual const nsCString& FontNameFor(const nsGlyphCode& aGlyphCode) const = 0;
// Getters for the parts
virtual nsGlyphCode ElementAt(DrawTarget* aDrawTarget,
@ -168,16 +160,14 @@ class nsPropertiesTable final : public nsGlyphTable {
explicit nsPropertiesTable(const nsACString& aPrimaryFontName)
: mState(NS_TABLE_STATE_EMPTY) {
MOZ_COUNT_CTOR(nsPropertiesTable);
mGlyphCodeFonts.AppendElement(FontFamilyName(
aPrimaryFontName, StyleFontFamilyNameSyntax::Identifiers));
mGlyphCodeFonts.AppendElement(aPrimaryFontName);
}
MOZ_COUNTED_DTOR(nsPropertiesTable)
const FontFamilyName& PrimaryFontName() const { return mGlyphCodeFonts[0]; }
const nsCString& PrimaryFontName() const { return mGlyphCodeFonts[0]; }
const FontFamilyName& FontNameFor(
const nsGlyphCode& aGlyphCode) const override {
const nsCString& FontNameFor(const nsGlyphCode& aGlyphCode) const override {
NS_ASSERTION(!aGlyphCode.IsGlyphID(),
"nsPropertiesTable can only access glyphs by code point");
return mGlyphCodeFonts[aGlyphCode.font];
@ -221,7 +211,7 @@ class nsPropertiesTable final : public nsGlyphTable {
// mGlyphCodeFonts[0] is the primary font associated to this table. The
// others are possible "external" fonts for glyphs not in the primary font
// but which are needed to stretch certain characters in the table
nsTArray<FontFamilyName> mGlyphCodeFonts;
nsTArray<nsCString> mGlyphCodeFonts;
// Tri-state variable for error/empty/ready
int32_t mState;
@ -259,13 +249,11 @@ nsGlyphCode nsPropertiesTable::ElementAt(DrawTarget* /* aDrawTarget */,
if (mState == NS_TABLE_STATE_ERROR) return kNullGlyph;
// Load glyph properties if this is the first time we have been here
if (mState == NS_TABLE_STATE_EMPTY) {
nsAutoCString primaryFontName;
mGlyphCodeFonts[0].AppendToString(primaryFontName);
nsresult rv = LoadProperties(primaryFontName, mGlyphProperties);
nsresult rv = LoadProperties(PrimaryFontName(), mGlyphProperties);
#ifdef DEBUG
nsAutoCString uriStr;
uriStr.AssignLiteral("resource://gre/res/fonts/mathfont");
uriStr.Append(primaryFontName);
uriStr.Append(PrimaryFontName());
uriStr.StripWhitespace(); // that may come from mGlyphCodeFonts
uriStr.AppendLiteral(".properties");
printf("Loading %s ... %s\n", uriStr.get(),
@ -284,12 +272,11 @@ nsGlyphCode nsPropertiesTable::ElementAt(DrawTarget* /* aDrawTarget */,
key.AssignLiteral("external.");
key.AppendInt(i, 10);
rv = mGlyphProperties->GetStringProperty(key, value);
if (NS_FAILED(rv)) break;
if (NS_FAILED(rv)) {
break;
}
Clean(value);
mGlyphCodeFonts.AppendElement(FontFamilyName(
NS_ConvertUTF16toUTF8(value),
StyleFontFamilyNameSyntax::Identifiers)); // i.e., mGlyphCodeFonts[i]
// holds this font name
mGlyphCodeFonts.AppendElement(NS_ConvertUTF16toUTF8(value));
}
}
@ -341,10 +328,6 @@ nsGlyphCode nsPropertiesTable::ElementAt(DrawTarget* /* aDrawTarget */,
NS_ERROR("Nonexistent font referenced in glyph table");
return kNullGlyph;
}
// The char cannot be handled if this font is not installed
if (!mGlyphCodeFonts[font].mName) {
return kNullGlyph;
}
}
buffer.Append(font);
}
@ -394,8 +377,7 @@ class nsOpenTypeTable final : public nsGlyphTable {
gfxFontGroup* aFontGroup, char16_t aChar,
bool aVertical) override;
const FontFamilyName& FontNameFor(
const nsGlyphCode& aGlyphCode) const override {
const nsCString& FontNameFor(const nsGlyphCode& aGlyphCode) const override {
NS_ASSERTION(aGlyphCode.IsGlyphID(),
"nsOpenTypeTable can only access glyphs by id");
return mFontFamilyName;
@ -417,13 +399,12 @@ class nsOpenTypeTable final : public nsGlyphTable {
private:
RefPtr<gfxFont> mFont;
FontFamilyName mFontFamilyName;
nsCString mFontFamilyName;
uint32_t mGlyphID;
explicit nsOpenTypeTable(gfxFont* aFont)
: mFont(aFont),
mFontFamilyName(aFont->GetFontEntry()->FamilyName(),
StyleFontFamilyNameSyntax::Identifiers),
mFontFamilyName(aFont->GetFontEntry()->FamilyName()),
mGlyphID(0) {
MOZ_COUNT_CTOR(nsOpenTypeTable);
}
@ -627,12 +608,9 @@ nsGlyphTable* nsGlyphTableList::AddGlyphTable(
nsGlyphTable* nsGlyphTableList::GetGlyphTableFor(const nsACString& aFamily) {
for (int32_t i = 0; i < PropertiesTableCount(); i++) {
nsPropertiesTable* glyphTable = PropertiesTableAt(i);
const FontFamilyName& primaryFontName = glyphTable->PrimaryFontName();
nsAutoCString primaryFontNameStr;
primaryFontName.AppendToString(primaryFontNameStr);
const nsCString& primaryFontName = glyphTable->PrimaryFontName();
// TODO: would be nice to consider StripWhitespace and other aliasing
if (primaryFontNameStr.Equals(aFamily,
nsCaseInsensitiveCStringComparator)) {
if (primaryFontName.Equals(aFamily, nsCaseInsensitiveCStringComparator)) {
return glyphTable;
}
}
@ -862,23 +840,21 @@ static nscoord ComputeSizeFromParts(nsPresContext* aPresContext,
bool nsMathMLChar::SetFontFamily(nsPresContext* aPresContext,
const nsGlyphTable* aGlyphTable,
const nsGlyphCode& aGlyphCode,
const FontFamilyList& aDefaultFamilyList,
const StyleFontFamilyList& aDefaultFamilyList,
nsFont& aFont,
RefPtr<gfxFontGroup>* aFontGroup) {
FontFamilyList glyphCodeFont;
StyleFontFamilyList glyphCodeFont;
if (aGlyphCode.font) {
nsTArray<FontFamilyName> names;
names.AppendElement(aGlyphTable->FontNameFor(aGlyphCode));
glyphCodeFont.SetFontlist(std::move(names));
glyphCodeFont = StyleFontFamilyList::WithOneUnquotedFamily(
aGlyphTable->FontNameFor(aGlyphCode));
}
const FontFamilyList& familyList =
const StyleFontFamilyList& familyList =
aGlyphCode.font ? glyphCodeFont : aDefaultFamilyList;
if (!*aFontGroup || !(aFont.fontlist == familyList)) {
if (!*aFontGroup || aFont.family.families != familyList) {
nsFont font = aFont;
font.fontlist = familyList;
font.family.families = familyList;
const nsStyleFont* styleFont = mComputedStyle->StyleFont();
nsFontMetrics::Params params;
params.language = styleFont->mLanguage;
@ -889,18 +865,31 @@ bool nsMathMLChar::SetFontFamily(nsPresContext* aPresContext,
params.featureValueLookup = aPresContext->GetFontFeatureValuesLookup();
RefPtr<nsFontMetrics> fm =
aPresContext->DeviceContext()->GetMetricsFor(font, params);
// Set the font if it is an unicode table
// or if the same family name has been found
gfxFont* firstFont = fm->GetThebesFontGroup()->GetFirstValidFont();
FontFamilyList firstFontList(firstFont->GetFontEntry()->FamilyName(),
StyleFontFamilyNameSyntax::Identifiers);
if (aGlyphTable == &gGlyphTableList->mUnicodeTable ||
firstFontList == familyList) {
aFont.fontlist = familyList;
*aFontGroup = fm->GetThebesFontGroup();
} else {
return false; // We did not set the font
// Set the font if it is an unicode table or if the same family name has
// been found.
const bool shouldSetFont = [&] {
if (aGlyphTable == &gGlyphTableList->mUnicodeTable) {
return true;
}
if (familyList.list.IsEmpty()) {
return false;
}
const auto& firstFontInList = familyList.list.AsSpan()[0];
gfxFont* firstFont = fm->GetThebesFontGroup()->GetFirstValidFont();
RefPtr<nsAtom> firstFontName =
NS_Atomize(firstFont->GetFontEntry()->FamilyName());
return firstFontInList.IsFamilyName() &&
firstFontInList.AsFamilyName().name.AsAtom() == firstFontName;
}();
if (!shouldSetFont) {
return false;
}
aFont.family.families = familyList;
*aFontGroup = fm->GetThebesFontGroup();
}
return true;
}
@ -927,7 +916,7 @@ class nsMathMLChar::StretchEnumContext {
nsStretchDirection aStretchDirection, nscoord aTargetSize,
uint32_t aStretchHint,
nsBoundingMetrics& aStretchedMetrics,
const FontFamilyList& aFamilyList, bool& aGlyphFound)
const StyleFontFamilyList& aFamilyList, bool& aGlyphFound)
: mChar(aChar),
mPresContext(aPresContext),
mDrawTarget(aDrawTarget),
@ -941,14 +930,13 @@ class nsMathMLChar::StretchEnumContext {
mTryParts(true),
mGlyphFound(aGlyphFound) {}
static bool EnumCallback(const FontFamilyName& aFamily, bool aGeneric,
void* aData);
static bool EnumCallback(const StyleSingleFontFamily& aFamily, void* aData);
private:
bool TryVariants(nsGlyphTable* aGlyphTable, RefPtr<gfxFontGroup>* aFontGroup,
const FontFamilyList& aFamilyList);
const StyleFontFamilyList& aFamilyList);
bool TryParts(nsGlyphTable* aGlyphTable, RefPtr<gfxFontGroup>* aFontGroup,
const FontFamilyList& aFamilyList);
const StyleFontFamilyList& aFamilyList);
nsMathMLChar* mChar;
nsPresContext* mPresContext;
@ -959,7 +947,7 @@ class nsMathMLChar::StretchEnumContext {
const uint32_t mStretchHint;
nsBoundingMetrics& mBoundingMetrics;
// Font families to search
const FontFamilyList& mFamilyList;
const StyleFontFamilyList& mFamilyList;
public:
bool mTryVariants;
@ -975,7 +963,7 @@ class nsMathMLChar::StretchEnumContext {
// Always updates the char if a better match is found.
bool nsMathMLChar::StretchEnumContext::TryVariants(
nsGlyphTable* aGlyphTable, RefPtr<gfxFontGroup>* aFontGroup,
const FontFamilyList& aFamilyList) {
const StyleFontFamilyList& aFamilyList) {
// Use our stretchy ComputedStyle now that stretching is in progress
ComputedStyle* sc = mChar->mComputedStyle;
nsFont font = sc->StyleFont()->mFont;
@ -1112,7 +1100,7 @@ bool nsMathMLChar::StretchEnumContext::TryVariants(
// Always updates the char if a better match is found.
bool nsMathMLChar::StretchEnumContext::TryParts(
nsGlyphTable* aGlyphTable, RefPtr<gfxFontGroup>* aFontGroup,
const FontFamilyList& aFamilyList) {
const StyleFontFamilyList& aFamilyList) {
// Use our stretchy ComputedStyle now that stretching is in progress
nsFont font = mChar->mComputedStyle->StyleFont()->mFont;
NormalizeDefaultFont(font, mFontSizeInflation);
@ -1279,13 +1267,14 @@ bool nsMathMLChar::StretchEnumContext::TryParts(
// Returns true iff stretching succeeded with the given family.
// This is called for each family, whether it exists or not.
bool nsMathMLChar::StretchEnumContext::EnumCallback(
const FontFamilyName& aFamily, bool aGeneric, void* aData) {
const StyleSingleFontFamily& aFamily, void* aData) {
StretchEnumContext* context = static_cast<StretchEnumContext*>(aData);
// for comparisons, force use of unquoted names
FontFamilyName unquotedFamilyName(aFamily);
if (unquotedFamilyName.mSyntax == StyleFontFamilyNameSyntax::Quoted) {
unquotedFamilyName.mSyntax = StyleFontFamilyNameSyntax::Identifiers;
StyleFontFamilyList family;
if (aFamily.IsFamilyName()) {
family = StyleFontFamilyList::WithOneUnquotedFamily(
nsAtomCString(aFamily.AsFamilyName().name.AsAtom()));
}
// Check font family if it is not a generic one
@ -1294,16 +1283,16 @@ bool nsMathMLChar::StretchEnumContext::EnumCallback(
nsFont font = sc->StyleFont()->mFont;
NormalizeDefaultFont(font, context->mFontSizeInflation);
RefPtr<gfxFontGroup> fontGroup;
FontFamilyList family(nsTArray<FontFamilyName>{unquotedFamilyName});
if (!aGeneric &&
if (!aFamily.IsGeneric() &&
!context->mChar->SetFontFamily(context->mPresContext, nullptr, kNullGlyph,
family, font, &fontGroup))
family, font, &fontGroup)) {
return false; // Could not set the family
}
// Determine the glyph table to use for this font.
UniquePtr<nsOpenTypeTable> openTypeTable;
nsGlyphTable* glyphTable;
if (aGeneric) {
if (aFamily.IsGeneric()) {
// This is a generic font, use the Unicode table.
glyphTable = &gGlyphTableList->mUnicodeTable;
} else {
@ -1316,9 +1305,8 @@ bool nsMathMLChar::StretchEnumContext::EnumCallback(
} else {
// Otherwise try to find a .properties file corresponding to that font
// family or fallback to the Unicode table.
nsAutoCString familyName;
unquotedFamilyName.AppendToString(familyName);
glyphTable = gGlyphTableList->GetGlyphTableFor(familyName);
glyphTable = gGlyphTableList->GetGlyphTableFor(
nsAtomCString(aFamily.AsFamilyName().name.AsAtom()));
}
}
@ -1333,7 +1321,7 @@ bool nsMathMLChar::StretchEnumContext::EnumCallback(
// If the unicode table is being used, then search all font families. If a
// special table is being used then the font in this family should have the
// specified glyphs.
const FontFamilyList& familyList =
const StyleFontFamilyList& familyList =
glyphTable == &gGlyphTableList->mUnicodeTable ? context->mFamilyList
: family;
@ -1343,22 +1331,23 @@ bool nsMathMLChar::StretchEnumContext::EnumCallback(
context->TryParts(glyphTable, &fontGroup, familyList));
}
static void AppendFallbacks(nsTArray<FontFamilyName>& aNames,
static void AppendFallbacks(nsTArray<StyleSingleFontFamily>& aNames,
const nsTArray<nsCString>& aFallbacks) {
for (const nsCString& fallback : aFallbacks) {
aNames.AppendElement(
FontFamilyName(fallback, StyleFontFamilyNameSyntax::Identifiers));
aNames.AppendElement(StyleSingleFontFamily::FamilyName(
StyleFamilyName{StyleAtom(NS_Atomize(fallback)),
StyleFontFamilyNameSyntax::Identifiers}));
}
}
// insert math fallback families just before the first generic or at the end
// when no generic present
static void InsertMathFallbacks(FontFamilyList& aFamilyList,
static void InsertMathFallbacks(StyleFontFamilyList& aFamilyList,
nsTArray<nsCString>& aFallbacks) {
nsTArray<FontFamilyName> mergedList;
nsTArray<StyleSingleFontFamily> mergedList;
bool inserted = false;
for (const FontFamilyName& name : aFamilyList.GetFontlist()->mNames) {
for (const auto& name : aFamilyList.list.AsSpan()) {
if (!inserted && name.IsGeneric()) {
inserted = true;
AppendFallbacks(mergedList, aFallbacks);
@ -1369,7 +1358,7 @@ static void InsertMathFallbacks(FontFamilyList& aFamilyList,
if (!inserted) {
AppendFallbacks(mergedList, aFallbacks);
}
aFamilyList.SetFontlist(std::move(mergedList));
aFamilyList = StyleFontFamilyList::WithNames(std::move(mergedList));
}
nsresult nsMathMLChar::StretchInternal(
@ -1510,7 +1499,7 @@ nsresult nsMathMLChar::StretchInternal(
gfxFontUtils::GetPrefsFontList("font.name.serif.x-math", mathFallbacks);
gfxFontUtils::AppendPrefsFontList("font.name-list.serif.x-math",
mathFallbacks);
InsertMathFallbacks(font.fontlist, mathFallbacks);
InsertMathFallbacks(font.family.families, mathFallbacks);
#ifdef NOISY_SEARCH
nsAutoString fontlistStr;
@ -1522,13 +1511,12 @@ nsresult nsMathMLChar::StretchInternal(
StretchEnumContext enumData(this, presContext, aDrawTarget,
aFontSizeInflation, aStretchDirection,
targetSize, aStretchHint, aDesiredStretchSize,
font.fontlist, glyphFound);
font.family.families, glyphFound);
enumData.mTryParts = !largeopOnly;
const nsTArray<FontFamilyName>& fontlist =
font.fontlist.GetFontlist()->mNames;
for (const FontFamilyName& name : fontlist) {
if (StretchEnumContext::EnumCallback(name, name.IsGeneric(), &enumData)) {
for (const StyleSingleFontFamily& name :
font.family.families.list.AsSpan()) {
if (StretchEnumContext::EnumCallback(name, &enumData)) {
if (name.IsNamedFamily(u"STIXGeneral"_ns)) {
AutoTArray<nsString, 1> params{
u"https://developer.mozilla.org/docs/Mozilla/"

View File

@ -196,7 +196,7 @@ class nsMathMLChar {
bool SetFontFamily(nsPresContext* aPresContext,
const nsGlyphTable* aGlyphTable,
const nsGlyphCode& aGlyphCode,
const mozilla::FontFamilyList& aDefaultFamily,
const mozilla::StyleFontFamilyList& aDefaultFamily,
nsFont& aFont, RefPtr<gfxFontGroup>* aFontGroup);
nsresult StretchInternal(nsIFrame* aForFrame, DrawTarget* aDrawTarget,

View File

@ -198,7 +198,7 @@ void FontFaceSet::RemoveDOMContentLoadedListener() {
}
void FontFaceSet::ParseFontShorthandForMatching(
const nsACString& aFont, RefPtr<SharedFontList>& aFamilyList,
const nsACString& aFont, StyleFontFamilyList& aFamilyList,
FontWeight& aWeight, FontStretch& aStretch, FontSlantStyle& aStyle,
ErrorResult& aRv) {
auto style = StyleComputedFontStyleDescriptor::Normal();
@ -249,7 +249,7 @@ void FontFaceSet::FindMatchingFontFaces(const nsACString& aFont,
const nsAString& aText,
nsTArray<FontFace*>& aFontFaces,
ErrorResult& aRv) {
RefPtr<SharedFontList> familyList;
StyleFontFamilyList familyList;
FontWeight weight;
FontStretch stretch;
FontSlantStyle italicStyle;
@ -271,13 +271,14 @@ void FontFaceSet::FindMatchingFontFaces(const nsACString& aFont,
// Set of FontFaces that we want to return.
nsTHashSet<FontFace*> matchingFaces;
for (const FontFamilyName& fontFamilyName : familyList->mNames) {
if (!fontFamilyName.IsNamed()) {
for (const StyleSingleFontFamily& fontFamilyName : familyList.list.AsSpan()) {
if (!fontFamilyName.IsFamilyName()) {
continue;
}
const auto& name = fontFamilyName.AsFamilyName();
RefPtr<gfxFontFamily> family =
mUserFontSet->LookupFamily(nsAtomCString(fontFamilyName.mName));
mUserFontSet->LookupFamily(nsAtomCString(name.name.AsAtom()));
if (!family) {
continue;

View File

@ -315,7 +315,7 @@ class FontFaceSet final : public DOMEventTargetHelper,
void UpdateHasLoadingFontFaces();
void ParseFontShorthandForMatching(const nsACString& aFont,
RefPtr<SharedFontList>& aFamilyList,
StyleFontFamilyList& aFamilyList,
FontWeight& aWeight, FontStretch& aStretch,
FontSlantStyle& aStyle, ErrorResult& aRv);
void FindMatchingFontFaces(const nsACString& aFont, const nsAString& aText,

View File

@ -11,7 +11,6 @@
#include "ChildIterator.h"
#include "ErrorReporter.h"
#include "GeckoProfiler.h"
#include "gfxFontFamilyList.h"
#include "gfxFontFeatures.h"
#include "gfxTextRun.h"
#include "imgLoader.h"
@ -973,42 +972,6 @@ void Gecko_AddRefAtom(nsAtom* aAtom) { NS_ADDREF(aAtom); }
void Gecko_ReleaseAtom(nsAtom* aAtom) { NS_RELEASE(aAtom); }
void Gecko_nsTArray_FontFamilyName_AppendNamed(
nsTArray<FontFamilyName>* aNames, nsAtom* aName,
StyleFontFamilyNameSyntax aSyntax) {
aNames->AppendElement(FontFamilyName(aName, aSyntax));
}
void Gecko_nsTArray_FontFamilyName_AppendGeneric(
nsTArray<FontFamilyName>* aNames, StyleGenericFontFamily aType) {
aNames->AppendElement(FontFamilyName(aType));
}
SharedFontList* Gecko_SharedFontList_Create() {
RefPtr<SharedFontList> fontlist = new SharedFontList();
return fontlist.forget().take();
}
MOZ_DEFINE_MALLOC_SIZE_OF(GeckoSharedFontListMallocSizeOf)
size_t Gecko_SharedFontList_SizeOfIncludingThisIfUnshared(
SharedFontList* aFontlist) {
MOZ_ASSERT(NS_IsMainThread());
return aFontlist->SizeOfIncludingThisIfUnshared(
GeckoSharedFontListMallocSizeOf);
}
size_t Gecko_SharedFontList_SizeOfIncludingThis(SharedFontList* aFontlist) {
MOZ_ASSERT(NS_IsMainThread());
return aFontlist->SizeOfIncludingThis(GeckoSharedFontListMallocSizeOf);
}
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(SharedFontList, SharedFontList);
void Gecko_CopyFontFamilyFrom(nsFont* dst, const nsFont* src) {
dst->fontlist = src->fontlist;
}
void Gecko_nsFont_InitSystem(nsFont* aDest, StyleSystemFont aFontId,
const nsStyleFont* aFont,
const Document* aDocument) {
@ -1033,7 +996,7 @@ StyleGenericFontFamily Gecko_nsStyleFont_ComputeDefaultFontType(
nsAtom* aLanguage) {
const nsFont* defaultFont =
ThreadSafeGetDefaultFontHelper(*aDoc, aLanguage, aGenericId);
return defaultFont->fontlist.GetDefaultFontType();
return defaultFont->family.families.fallback;
}
gfxFontFeatureValueSet* Gecko_ConstructFontFeatureValueSet() {
@ -1362,15 +1325,6 @@ void Gecko_nsStyleFont_CopyLangFrom(nsStyleFont* aFont,
aFont->mLanguage = aSource->mLanguage;
}
void Gecko_nsStyleFont_PrioritizeUserFonts(
nsStyleFont* aFont, StyleGenericFontFamily aDefaultGeneric) {
MOZ_ASSERT(!StaticPrefs::browser_display_use_document_fonts());
MOZ_ASSERT(aDefaultGeneric != StyleGenericFontFamily::None);
if (!aFont->mFont.fontlist.PrioritizeFirstGeneric()) {
aFont->mFont.fontlist.PrependGeneric(aDefaultGeneric);
}
}
Length Gecko_nsStyleFont_ComputeMinSize(const nsStyleFont* aFont,
const Document* aDocument) {
// Don't change font-size:0, since that would un-hide hidden text,
@ -1791,3 +1745,76 @@ nsAtom** Gecko_Element_ExportedParts(const nsAttrValue* aValue,
static_assert(alignof(RefPtr<nsAtom>) == alignof(nsAtom*));
return reinterpret_cast<nsAtom**>(parts->Elements());
}
bool StyleSingleFontFamily::IsNamedFamily(const nsAString& aFamilyName) const {
if (!IsFamilyName()) {
return false;
}
nsDependentAtomString name(AsFamilyName().name.AsAtom());
return name.Equals(aFamilyName, nsCaseInsensitiveStringComparator);
}
StyleSingleFontFamily StyleSingleFontFamily::Parse(
const nsACString& aFamilyOrGenericName) {
// should only be passed a single font - not entirely correct, a family
// *could* have a comma in it but in practice never does so
// for debug purposes this is fine
NS_ASSERTION(aFamilyOrGenericName.FindChar(',') == -1,
"Convert method should only be passed a single family name");
auto genericType = Servo_GenericFontFamily_Parse(&aFamilyOrGenericName);
if (genericType != StyleGenericFontFamily::None) {
return Generic(genericType);
}
return FamilyName({StyleAtom(NS_Atomize(aFamilyOrGenericName)),
StyleFontFamilyNameSyntax::Identifiers});
}
void StyleSingleFontFamily::AppendToString(nsACString& aName,
bool aQuote) const {
if (IsFamilyName()) {
const auto& name = AsFamilyName();
bool quote = aQuote && name.syntax == StyleFontFamilyNameSyntax::Quoted;
if (quote) {
aName.Append('"');
}
aName.Append(nsAtomCString(name.name.AsAtom()));
if (quote) {
aName.Append('"');
}
return;
}
switch (AsGeneric()) {
case StyleGenericFontFamily::None:
case StyleGenericFontFamily::MozEmoji:
MOZ_FALLTHROUGH_ASSERT("Should never appear in a font-family name!");
case StyleGenericFontFamily::Serif:
return aName.AppendLiteral("serif");
case StyleGenericFontFamily::SansSerif:
return aName.AppendLiteral("sans-serif");
case StyleGenericFontFamily::Monospace:
return aName.AppendLiteral("monospace");
case StyleGenericFontFamily::Cursive:
return aName.AppendLiteral("cursive");
case StyleGenericFontFamily::Fantasy:
return aName.AppendLiteral("fantasy");
}
MOZ_ASSERT_UNREACHABLE("Unknown generic font-family!");
return aName.AppendLiteral("serif");
}
StyleFontFamilyList StyleFontFamilyList::WithNames(
nsTArray<StyleSingleFontFamily>&& aNames) {
StyleFontFamilyList list;
Servo_FontFamilyList_WithNames(&aNames, &list);
return list;
}
StyleFontFamilyList StyleFontFamilyList::WithOneUnquotedFamily(
const nsACString& aName) {
AutoTArray<StyleSingleFontFamily, 1> names;
names.AppendElement(StyleSingleFontFamily::FamilyName(
{StyleAtom(NS_Atomize(aName)), StyleFontFamilyNameSyntax::Identifiers}));
return WithNames(std::move(names));
}

View File

@ -35,12 +35,10 @@ class ComputedStyle;
class SeenPtrs;
class ServoElementSnapshot;
class ServoElementSnapshotTable;
class SharedFontList;
class StyleSheet;
enum class PseudoStyleType : uint8_t;
enum class PointerCapabilities : uint8_t;
enum class UpdateAnimationsTasks : uint8_t;
struct FontFamilyName;
struct Keyframe;
namespace css {
@ -273,27 +271,6 @@ nsAtom* Gecko_Atomize16(const nsAString* aString);
void Gecko_AddRefAtom(nsAtom* aAtom);
void Gecko_ReleaseAtom(nsAtom* aAtom);
// Font style
void Gecko_CopyFontFamilyFrom(nsFont* dst, const nsFont* src);
void Gecko_nsTArray_FontFamilyName_AppendNamed(
nsTArray<mozilla::FontFamilyName>* aNames, nsAtom* aName,
mozilla::StyleFontFamilyNameSyntax);
void Gecko_nsTArray_FontFamilyName_AppendGeneric(
nsTArray<mozilla::FontFamilyName>* aNames, mozilla::StyleGenericFontFamily);
// Returns an already-AddRefed SharedFontList with an empty mNames array.
mozilla::SharedFontList* Gecko_SharedFontList_Create();
size_t Gecko_SharedFontList_SizeOfIncludingThis(
mozilla::SharedFontList* fontlist);
size_t Gecko_SharedFontList_SizeOfIncludingThisIfUnshared(
mozilla::SharedFontList* fontlist);
NS_DECL_THREADSAFE_FFI_REFCOUNTING(mozilla::SharedFontList, SharedFontList);
// will not run destructors on dst, give it uninitialized memory
// font_id is LookAndFeel::FontID
void Gecko_nsFont_InitSystem(nsFont* dst, mozilla::StyleSystemFont font_id,
@ -502,14 +479,6 @@ void Gecko_nsStyleFont_SetLang(nsStyleFont* font, nsAtom* atom);
void Gecko_nsStyleFont_CopyLangFrom(nsStyleFont* aFont,
const nsStyleFont* aSource);
// Moves the generic family in the font-family to the front, or prepends
// aDefaultGeneric, so that user-configured fonts take precedent over document
// fonts.
//
// Document fonts may still be used as fallback for unsupported glyphs though.
void Gecko_nsStyleFont_PrioritizeUserFonts(
nsStyleFont* font, mozilla::StyleGenericFontFamily aDefaultGeneric);
mozilla::Length Gecko_nsStyleFont_ComputeMinSize(const nsStyleFont*,
const mozilla::dom::Document*);

View File

@ -245,8 +245,6 @@ whitelist-types = [
"DefaultDelete",
"DOMIntersectionObserverEntry",
"Element",
"FontFamilyList",
"FontFamilyName",
"mozilla::FontSizePrefs",
"FragmentOrURL",
"FrameRequestCallback",
@ -507,6 +505,7 @@ cbindgen-types = [
{ gecko = "StyleOwnedOrNull", servo = "crate::gecko_bindings::sugar::ownership::OwnedOrNull" },
{ gecko = "StyleStrong", servo = "crate::gecko_bindings::sugar::ownership::Strong" },
{ gecko = "StyleGenericFontFamily", servo = "crate::values::computed::font::GenericFontFamily" },
{ gecko = "StyleFontFamily", servo = "crate::values::computed::font::FontFamily" },
{ gecko = "StyleGenericFontSizeAdjust", servo = "crate::values::generics::font::GenericFontSizeAdjust" },
{ gecko = "StyleFontFamilyNameSyntax", servo = "crate::values::computed::font::FontFamilyNameSyntax" },
{ gecko = "StyleGenericColor", servo = "crate::values::generics::color::Color" },

View File

@ -58,7 +58,7 @@ bool ServoCSSParser::ParseTransformIntoMatrix(const nsACString& aValue,
/* static */
bool ServoCSSParser::ParseFontShorthandForMatching(
const nsACString& aValue, URLExtraData* aUrl, RefPtr<SharedFontList>& aList,
const nsACString& aValue, URLExtraData* aUrl, StyleFontFamilyList& aList,
StyleComputedFontStyleDescriptor& aStyle, float& aStretch, float& aWeight) {
return Servo_ParseFontShorthandForMatching(&aValue, aUrl, &aList, &aStyle,
&aStretch, &aWeight);

View File

@ -26,8 +26,8 @@ class RefPtr;
namespace mozilla {
class ServoStyleSet;
class SharedFontList;
struct URLExtraData;
struct StyleFontFamilyList;
union StyleComputedFontStyleDescriptor;
namespace css {
@ -122,9 +122,9 @@ class ServoCSSParser {
* @return Whether the value was successfully parsed.
*/
static bool ParseFontShorthandForMatching(
const nsACString& aValue, URLExtraData* aUrl,
RefPtr<SharedFontList>& aList, StyleComputedFontStyleDescriptor& aStyle,
float& aStretch, float& aWeight);
const nsACString& aValue, URLExtraData* aUrl, StyleFontFamilyList& aList,
StyleComputedFontStyleDescriptor& aStyle, float& aStretch,
float& aWeight);
/**
* Get a URLExtraData from a document.

View File

@ -1046,6 +1046,18 @@ inline AspectRatio StyleAspectRatio::ToLayoutRatio() const {
: AspectRatio();
}
inline bool StyleFontFamilyList::ContainsFallback() const {
if (fallback == StyleGenericFontFamily::None) {
return false;
}
for (const auto& family : list.AsSpan()) {
if (family.IsGeneric() && family.AsGeneric() == fallback) {
return true;
}
}
return false;
}
} // namespace mozilla
#endif

View File

@ -35,6 +35,17 @@ enum class FontUsageKind {
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(FontUsageKind);
static bool IsFontReferenced(const ComputedStyle& aStyle,
const nsAString& aFamilyName) {
for (const auto& family :
aStyle.StyleFont()->mFont.family.families.list.AsSpan()) {
if (family.IsNamedFamily(aFamilyName)) {
return true;
}
}
return false;
}
static FontUsageKind StyleFontUsage(nsIFrame* aFrame, ComputedStyle* aStyle,
nsPresContext* aPresContext,
const gfxUserFontEntry* aFont,
@ -44,7 +55,7 @@ static FontUsageKind StyleFontUsage(nsIFrame* aFrame, ComputedStyle* aStyle,
auto FontIsUsed = [&aFont, &aPresContext,
&aFamilyName](ComputedStyle* aStyle) {
if (!aStyle->StyleFont()->mFont.fontlist.Contains(aFamilyName)) {
if (!IsFontReferenced(*aStyle, aFamilyName)) {
return false;
}
@ -161,8 +172,8 @@ void nsFontFaceUtils::MarkDirtyForFontChange(nsIFrame* aSubtreeRoot,
nsPresContext* pc = aSubtreeRoot->PresContext();
PresShell* presShell = pc->PresShell();
// gfxFontFamilyList::Contains expects a UTF-16 string. Convert it once
// here rather than on each call.
// StyleSingleFontFamily::IsNamedFamily expects a UTF-16 string. Convert it
// once here rather than on each call.
NS_ConvertUTF8toUTF16 familyName(aFont->FamilyName());
// check descendants, iterating over subtrees that may include

View File

@ -207,7 +207,6 @@ nsStyleFont::nsStyleFont(const nsStyleFont& aSrc)
mFontSizeFactor(aSrc.mFontSizeFactor),
mFontSizeOffset(aSrc.mFontSizeOffset),
mFontSizeKeyword(aSrc.mFontSizeKeyword),
mGenericID(aSrc.mGenericID),
mMathDepth(aSrc.mMathDepth),
mMathVariant(aSrc.mMathVariant),
mMathStyle(aSrc.mMathStyle),
@ -228,7 +227,6 @@ nsStyleFont::nsStyleFont(const Document& aDocument)
mFontSizeFactor(1.0),
mFontSizeOffset{0},
mFontSizeKeyword(StyleFontSizeKeyword::Medium),
mGenericID(StyleGenericFontFamily::None),
mMathDepth(0),
mMathVariant(NS_MATHML_MATHVARIANT_NONE),
mMathStyle(NS_STYLE_MATH_STYLE_NORMAL),
@ -275,7 +273,7 @@ nsChangeHint nsStyleFont::CalcDifference(const nsStyleFont& aNewData) const {
}
// XXX Should any of these cause a non-nsChangeHint_NeutralChange change?
if (mGenericID != aNewData.mGenericID || mMathDepth != aNewData.mMathDepth ||
if (mMathDepth != aNewData.mMathDepth ||
mScriptUnconstrainedSize != aNewData.mScriptUnconstrainedSize ||
mScriptMinSize != aNewData.mScriptMinSize ||
mScriptSizeMultiplier != aNewData.mScriptSizeMultiplier) {

View File

@ -100,8 +100,6 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleFont {
mozilla::Length mFontSizeOffset;
mozilla::StyleFontSizeKeyword mFontSizeKeyword;
mozilla::StyleGenericFontFamily mGenericID;
// math-depth support (used for MathML scriptlevel)
int8_t mMathDepth;
// MathML mathvariant support

View File

@ -308,11 +308,6 @@ impl_threadsafe_refcount!(
bindings::Gecko_AddRefnsIURIArbitraryThread,
bindings::Gecko_ReleasensIURIArbitraryThread
);
impl_threadsafe_refcount!(
structs::SharedFontList,
bindings::Gecko_AddRefSharedFontListArbitraryThread,
bindings::Gecko_ReleaseSharedFontListArbitraryThread
);
impl_threadsafe_refcount!(
structs::SheetLoadDataHolder,
bindings::Gecko_AddRefSheetLoadDataHolderArbitraryThread,

View File

@ -885,18 +885,19 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
// System fonts are all right, and should have the default font type
// set to none already, so bail out early.
if font.mFont.systemFont {
if font.mFont.family.is_system_font {
debug_assert_eq!(
font.mFont.fontlist.mDefaultFontType,
font.mFont.family.families.fallback,
GenericFontFamily::None
);
return;
}
let generic = font.mFont.family.families.single_generic().unwrap_or(GenericFontFamily::None);
let default_font_type = unsafe {
bindings::Gecko_nsStyleFont_ComputeDefaultFontType(
builder.device.document(),
font.mGenericID,
generic,
font.mLanguage.mRawPtr,
)
};
@ -906,15 +907,15 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
// cursive or fantasy, since they're ignored, see bug 789788), and
// we have a generic family to actually replace it with.
let prioritize_user_fonts = !use_document_fonts &&
default_font_type != GenericFontFamily::None &&
matches!(
font.mGenericID,
generic,
GenericFontFamily::None |
GenericFontFamily::Fantasy |
GenericFontFamily::Cursive
) &&
default_font_type != GenericFontFamily::None;
);
if !prioritize_user_fonts && default_font_type == font.mFont.fontlist.mDefaultFontType {
if !prioritize_user_fonts && default_font_type == font.mFont.family.families.fallback {
// Nothing to do.
return;
}
@ -922,9 +923,9 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
};
let font = builder.mutate_font().gecko_mut();
font.mFont.fontlist.mDefaultFontType = default_font_type;
font.mFont.family.families.fallback = default_font_type;
if prioritize_user_fonts {
unsafe { bindings::Gecko_nsStyleFont_PrioritizeUserFonts(font, default_font_type) }
font.mFont.family.families.prioritize_first_generic_or_prepend(default_font_type);
}
}

View File

@ -22,7 +22,6 @@ use crate::gecko_bindings::bindings::Gecko_CopyConstruct_${style_struct.gecko_ff
use crate::gecko_bindings::bindings::Gecko_Destroy_${style_struct.gecko_ffi_name};
% endfor
use crate::gecko_bindings::bindings::Gecko_CopyCounterStyle;
use crate::gecko_bindings::bindings::Gecko_CopyFontFamilyFrom;
use crate::gecko_bindings::bindings::Gecko_EnsureImageLayersLength;
use crate::gecko_bindings::bindings::Gecko_nsStyleFont_SetLang;
use crate::gecko_bindings::bindings::Gecko_nsStyleFont_CopyLangFrom;
@ -848,52 +847,6 @@ fn static_assert() {
<% impl_font_settings("font_feature_settings", "gfxFontFeature", "FeatureTagValue", "i32", "u32") %>
<% impl_font_settings("font_variation_settings", "gfxFontVariation", "VariationValue", "f32", "f32") %>
pub fn set_font_family(&mut self, v: longhands::font_family::computed_value::T) {
use crate::values::computed::font::GenericFontFamily;
let is_system_font = v.is_system_font;
self.gecko.mFont.systemFont = is_system_font;
self.gecko.mGenericID = if is_system_font {
GenericFontFamily::None
} else {
v.families.single_generic().unwrap_or(GenericFontFamily::None)
};
self.gecko.mFont.fontlist.mFontlist.mBasePtr.set_move(
v.families.shared_font_list().clone()
);
// Fixed-up if needed in Cascade::fixup_font_stuff.
self.gecko.mFont.fontlist.mDefaultFontType = GenericFontFamily::None;
}
pub fn copy_font_family_from(&mut self, other: &Self) {
unsafe { Gecko_CopyFontFamilyFrom(&mut self.gecko.mFont, &other.gecko.mFont); }
self.gecko.mGenericID = other.gecko.mGenericID;
self.gecko.mFont.systemFont = other.gecko.mFont.systemFont;
}
pub fn reset_font_family(&mut self, other: &Self) {
self.copy_font_family_from(other)
}
pub fn clone_font_family(&self) -> longhands::font_family::computed_value::T {
use crate::values::computed::font::{FontFamily, SingleFontFamily, FontFamilyList};
let fontlist = &self.gecko.mFont.fontlist;
let shared_fontlist = unsafe { fontlist.mFontlist.mBasePtr.to_safe() };
let families = if shared_fontlist.mNames.is_empty() {
let default = SingleFontFamily::Generic(fontlist.mDefaultFontType);
FontFamilyList::new(Box::new([default]))
} else {
FontFamilyList::SharedFontList(shared_fontlist)
};
FontFamily {
families,
is_system_font: self.gecko.mFont.systemFont,
}
}
pub fn unzoom_fonts(&mut self, device: &Device) {
use crate::values::generics::NonNegative;
self.gecko.mSize = NonNegative(device.unzoom_text(self.gecko.mSize.0));
@ -1001,6 +954,8 @@ fn static_assert() {
${impl_simple("font_size_adjust", "mFont.sizeAdjust")}
${impl_simple("font_family", "mFont.family")}
#[allow(non_snake_case)]
pub fn set__x_lang(&mut self, v: longhands::_x_lang::computed_value::T) {
let ptr = v.0.as_ptr();

View File

@ -314,7 +314,6 @@ pub mod system_font {
//! variable reference. We may want to improve this behavior at some
//! point. See also https://github.com/w3c/csswg-drafts/issues/1586.
use crate::values::computed::font::GenericFontFamily;
use crate::properties::longhands;
use std::hash::{Hash, Hasher};
use crate::values::computed::{ToComputedValue, Context};
@ -356,7 +355,7 @@ pub mod system_font {
use std::mem;
use crate::values::computed::Percentage;
use crate::values::specified::font::KeywordInfo;
use crate::values::computed::font::{FontFamily, FontSize, FontStretch, FontStyle, FontFamilyList};
use crate::values::computed::font::{FontSize, FontStretch, FontStyle};
use crate::values::generics::NonNegative;
let mut system = mem::MaybeUninit::<nsFont>::uninit();
@ -375,12 +374,7 @@ pub mod system_font {
})));
let font_style = FontStyle::from_gecko(system.style);
let ret = ComputedSystemFont {
font_family: FontFamily {
families: FontFamilyList::SharedFontList(
unsafe { system.fontlist.mFontlist.mBasePtr.to_safe() }
),
is_system_font: true,
},
font_family: system.family.clone(),
font_size: FontSize {
size: NonNegative(cx.maybe_zoom_text(system.size.0)),
keyword_info: KeywordInfo::none()
@ -403,7 +397,6 @@ pub mod system_font {
font_variation_settings: longhands::font_variation_settings::get_initial_value(),
font_variant_alternates: longhands::font_variant_alternates::get_initial_value(),
system_font: *self,
default_font_type: system.fontlist.mDefaultFontType,
};
unsafe { bindings::Gecko_nsFont_Destroy(system); }
ret
@ -435,7 +428,6 @@ pub mod system_font {
pub ${name}: longhands::${name}::computed_value::T,
% endfor
pub system_font: SystemFont,
pub default_font_type: GenericFontFamily,
}
}

View File

@ -829,7 +829,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
/// the same font as its fallback ('list-style-type') in case it fails to load.
#[cfg(feature = "gecko")]
fn adjust_for_marker_pseudo(&mut self) {
use crate::values::computed::font::{FamilyName, FontFamily, FontFamilyList, FontFamilyNameSyntax, FontSynthesis, SingleFontFamily};
use crate::values::computed::font::{FontFamily, FontSynthesis};
use crate::values::computed::text::{LetterSpacing, WordSpacing};
let is_legacy_marker = self.style.pseudo.map_or(false, |p| p.is_marker()) &&
@ -839,14 +839,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
return;
}
if !self.style.flags.get().contains(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_FONT_FAMILY) {
let moz_bullet_font_family = FontFamily {
families: FontFamilyList::new(Box::new([SingleFontFamily::FamilyName(FamilyName {
name: atom!("-moz-bullet-font"),
syntax: FontFamilyNameSyntax::Identifiers,
})])),
is_system_font: false,
};
self.style.mutate_font().set_font_family(moz_bullet_font_family);
self.style.mutate_font().set_font_family(FontFamily::moz_bullet().clone());
// FIXME(mats): We can remove this if support for font-synthesis is added to @font-face rules.
// Then we can add it to the @font-face rule in html.css instead.

View File

@ -4,8 +4,6 @@
//! Computed values for font properties
#[cfg(feature = "gecko")]
use crate::gecko_bindings::sugar::refptr::RefPtr;
#[cfg(feature = "gecko")]
use crate::gecko_bindings::{bindings, structs};
use crate::values::animated::ToAnimatedValue;
@ -26,13 +24,7 @@ use cssparser::{serialize_identifier, CssStringWriter, Parser};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use std::fmt::{self, Write};
use std::hash::{Hash, Hasher};
#[cfg(feature = "gecko")]
use std::mem::{self, ManuallyDrop};
#[cfg(feature = "servo")]
use std::slice;
use style_traits::{CssWriter, ParseError, ToCss};
#[cfg(feature = "gecko")]
use to_shmem::{self, SharedMemoryBuilder, ToShmem};
pub use crate::values::computed::Length as MozScriptMinSize;
pub use crate::values::specified::font::{FontSynthesis, MozScriptSizeMultiplier};
@ -183,6 +175,7 @@ impl ToAnimatedValue for FontSize {
#[derive(Clone, Debug, Eq, PartialEq, ToComputedValue, ToResolvedValue)]
#[cfg_attr(feature = "servo", derive(Hash, MallocSizeOf, Serialize, Deserialize))]
/// Specifies a prioritized list of font family names or generic family names.
#[repr(C)]
pub struct FontFamily {
/// The actual list of family names.
pub families: FontFamilyList,
@ -190,27 +183,95 @@ pub struct FontFamily {
pub is_system_font: bool,
}
macro_rules! static_font_family {
($ident:ident, $family:expr) => {
lazy_static! {
static ref $ident: FontFamily = FontFamily {
families: FontFamilyList {
list: crate::ArcSlice::from_iter_leaked(std::iter::once($family)),
fallback: GenericFontFamily::None,
},
is_system_font: false,
};
}
};
}
impl FontFamily {
#[inline]
/// Get default font family as `serif` which is a generic font-family
pub fn serif() -> Self {
FontFamily {
families: FontFamilyList::new(Box::new([SingleFontFamily::Generic(
GenericFontFamily::Serif,
)])),
is_system_font: false,
Self::generic(GenericFontFamily::Serif).clone()
}
/// Returns the font family for `-moz-bullet-font`.
pub(crate) fn moz_bullet() -> &'static Self {
static_font_family!(MOZ_BULLET, SingleFontFamily::FamilyName(FamilyName {
name: atom!("-moz-bullet-font"),
syntax: FontFamilyNameSyntax::Identifiers,
}));
&*MOZ_BULLET
}
/// Returns a font family for a single system font.
pub fn for_system_font(name: &str) -> Self {
Self {
families: FontFamilyList {
list: crate::ArcSlice::from_iter(std::iter::once(SingleFontFamily::FamilyName(FamilyName {
name: Atom::from(name),
syntax: FontFamilyNameSyntax::Identifiers,
}))),
fallback: GenericFontFamily::None,
},
is_system_font: true,
}
}
/// Returns a generic font family.
pub fn generic(generic: GenericFontFamily) -> &'static Self {
macro_rules! generic_font_family {
($ident:ident, $family:ident) => {
static_font_family!($ident, SingleFontFamily::Generic(GenericFontFamily::$family))
}
}
generic_font_family!(SERIF, Serif);
generic_font_family!(SANS_SERIF, SansSerif);
generic_font_family!(MONOSPACE, Monospace);
generic_font_family!(CURSIVE, Cursive);
generic_font_family!(FANTASY, Fantasy);
generic_font_family!(MOZ_EMOJI, MozEmoji);
match generic {
GenericFontFamily::None => {
debug_assert!(false, "Bogus caller!");
&*SERIF
}
GenericFontFamily::Serif => &*SERIF,
GenericFontFamily::SansSerif => &*SANS_SERIF,
GenericFontFamily::Monospace => &*MONOSPACE,
GenericFontFamily::Cursive => &*CURSIVE,
GenericFontFamily::Fantasy => &*FANTASY,
GenericFontFamily::MozEmoji => &*MOZ_EMOJI,
}
}
}
#[cfg(feature = "gecko")]
impl MallocSizeOf for FontFamily {
fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
// SharedFontList objects are generally shared from the pointer
// stored in the specified value. So only count this if the
// SharedFontList is unshared.
let shared_font_list = self.families.shared_font_list().get();
unsafe { bindings::Gecko_SharedFontList_SizeOfIncludingThisIfUnshared(shared_font_list) }
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
use malloc_size_of::MallocUnconditionalSizeOf;
// SharedFontList objects are generally measured from the pointer stored
// in the specified value. So only count this if the SharedFontList is
// unshared.
let shared_font_list = &self.families.list;
if shared_font_list.is_unique() {
shared_font_list.unconditional_size_of(ops)
} else {
0
}
}
}
@ -220,7 +281,10 @@ impl ToCss for FontFamily {
W: fmt::Write,
{
let mut iter = self.families.iter();
iter.next().unwrap().to_css(dest)?;
match iter.next() {
Some(f) => f.to_css(dest)?,
None => return self.families.fallback.to_css(dest),
}
for family in iter {
dest.write_str(", ")?;
family.to_css(dest)?;
@ -229,15 +293,16 @@ impl ToCss for FontFamily {
}
}
/// The name of a font family of choice.
#[derive(
Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem,
)]
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
/// The name of a font family of choice
#[repr(C)]
pub struct FamilyName {
/// Name of the font family
/// Name of the font family.
pub name: Atom,
/// Syntax of the font family
/// Syntax of the font family.
pub syntax: FontFamilyNameSyntax,
}
@ -291,11 +356,13 @@ pub enum FontFamilyNameSyntax {
Identifiers,
}
/// A set of faces that vary in weight, width or slope.
/// cbindgen:derive-mut-casts=true
#[derive(
Clone, Debug, Eq, MallocSizeOf, PartialEq, ToCss, ToComputedValue, ToResolvedValue, ToShmem,
)]
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize, Hash))]
/// A set of faces that vary in weight, width or slope.
#[repr(u8)]
pub enum SingleFontFamily {
/// The name of a font family of choice.
FamilyName(FamilyName),
@ -429,145 +496,57 @@ impl SingleFontFamily {
syntax: FontFamilyNameSyntax::Quoted,
})
}
#[cfg(feature = "gecko")]
/// Get the corresponding font-family with family name
fn from_font_family_name(family: &structs::FontFamilyName) -> SingleFontFamily {
if family.mName.mRawPtr.is_null() {
debug_assert_ne!(family.mGeneric, GenericFontFamily::None);
return SingleFontFamily::Generic(family.mGeneric);
}
let name = unsafe { Atom::from_raw(family.mName.mRawPtr) };
SingleFontFamily::FamilyName(FamilyName {
name,
syntax: family.mSyntax,
})
}
}
#[cfg(feature = "servo")]
#[derive(
Clone,
Debug,
Deserialize,
Eq,
Hash,
MallocSizeOf,
PartialEq,
Serialize,
ToComputedValue,
ToResolvedValue,
ToShmem,
)]
/// A list of SingleFontFamily
pub struct FontFamilyList(Box<[SingleFontFamily]>);
#[cfg(feature = "gecko")]
#[derive(Clone, Debug, ToComputedValue, ToResolvedValue)]
/// A list of SingleFontFamily
pub enum FontFamilyList {
/// A strong reference to a Gecko SharedFontList object.
SharedFontList(
#[compute(no_field_bound)]
#[resolve(no_field_bound)]
RefPtr<structs::SharedFontList>,
),
/// A font-family generic ID.
Generic(GenericFontFamily),
/// A list of font families.
#[derive(Clone, Debug, ToComputedValue, ToResolvedValue, ToShmem, PartialEq, Eq)]
#[repr(C)]
pub struct FontFamilyList {
/// The actual list of font families specified.
pub list: crate::ArcSlice<SingleFontFamily>,
/// A fallback font type (none, serif, or sans-serif, generally).
pub fallback: GenericFontFamily,
}
#[cfg(feature = "gecko")]
impl ToShmem for FontFamilyList {
fn to_shmem(&self, _builder: &mut SharedMemoryBuilder) -> to_shmem::Result<Self> {
// In practice, the only SharedFontList objects we create from shared
// style sheets are ones with a single generic entry.
Ok(ManuallyDrop::new(match *self {
FontFamilyList::SharedFontList(ref r) => {
if !(r.mNames.len() == 1 && r.mNames[0].mName.mRawPtr.is_null()) {
return Err(String::from(
"ToShmem failed for FontFamilyList: cannot handle non-generic families",
));
}
FontFamilyList::Generic(r.mNames[0].mGeneric)
},
FontFamilyList::Generic(t) => FontFamilyList::Generic(t),
}))
}
}
#[cfg(feature = "gecko")]
impl PartialEq for FontFamilyList {
fn eq(&self, other: &FontFamilyList) -> bool {
let self_list = self.shared_font_list();
let other_list = other.shared_font_list();
if self_list.mNames.len() != other_list.mNames.len() {
return false;
}
for (a, b) in self_list.mNames.iter().zip(other_list.mNames.iter()) {
if a.mSyntax != b.mSyntax ||
a.mName.mRawPtr != b.mName.mRawPtr ||
a.mGeneric != b.mGeneric
{
return false;
}
}
true
}
}
#[cfg(feature = "gecko")]
impl Eq for FontFamilyList {}
impl FontFamilyList {
/// Return FontFamilyList with a vector of SingleFontFamily
#[cfg(feature = "servo")]
pub fn new(families: Box<[SingleFontFamily]>) -> FontFamilyList {
FontFamilyList(families)
/// Return iterator of SingleFontFamily
pub fn iter(&self) -> impl Iterator<Item = &SingleFontFamily> {
self.list.iter()
}
/// Return FontFamilyList with a vector of SingleFontFamily
#[cfg(feature = "gecko")]
pub fn new(families: Box<[SingleFontFamily]>) -> FontFamilyList {
let fontlist;
let names;
unsafe {
fontlist = bindings::Gecko_SharedFontList_Create();
names = &mut (*fontlist).mNames;
names.ensure_capacity(families.len());
/// Puts the fallback in the list if needed.
pub fn normalize(&mut self) {
if self.fallback == GenericFontFamily::None {
return;
}
let mut new_list = self.list.iter().cloned().collect::<Vec<_>>();
new_list.push(SingleFontFamily::Generic(self.fallback));
self.list = crate::ArcSlice::from_iter(new_list.into_iter());
}
/// If there's a generic font family on the list (which isn't cursive or
/// fantasy), then move it to the front of the list. Otherwise, prepend the
/// default generic.
pub (crate) fn prioritize_first_generic_or_prepend(&mut self, generic: GenericFontFamily) {
let index_of_first_generic = self.iter().position(|f| {
match *f {
SingleFontFamily::Generic(f) => f != GenericFontFamily::Cursive && f != GenericFontFamily::Fantasy,
_ => false,
}
});
if let Some(0) = index_of_first_generic {
return; // Already first
}
let mut new_list = self.list.iter().cloned().collect::<Vec<_>>();
let element_to_prepend = match index_of_first_generic {
Some(i) => new_list.remove(i),
None => SingleFontFamily::Generic(generic),
};
for family in families.iter() {
match *family {
SingleFontFamily::FamilyName(ref f) => unsafe {
bindings::Gecko_nsTArray_FontFamilyName_AppendNamed(
names,
f.name.as_ptr(),
f.syntax,
);
},
SingleFontFamily::Generic(family) => unsafe {
bindings::Gecko_nsTArray_FontFamilyName_AppendGeneric(names, family);
},
}
}
FontFamilyList::SharedFontList(unsafe { RefPtr::from_addrefed(fontlist) })
}
/// Return iterator of SingleFontFamily
#[cfg(feature = "servo")]
pub fn iter(&self) -> slice::Iter<SingleFontFamily> {
self.0.iter()
}
/// Return iterator of SingleFontFamily
#[cfg(feature = "gecko")]
pub fn iter(&self) -> FontFamilyNameIter {
FontFamilyNameIter {
names: &self.shared_font_list().mNames,
cur: 0,
}
new_list.insert(0, element_to_prepend);
self.list = crate::ArcSlice::from_iter(new_list.into_iter());
}
/// Return the generic ID if it is a single generic font
@ -580,46 +559,6 @@ impl FontFamilyList {
}
None
}
/// Return a reference to the Gecko SharedFontList.
#[cfg(feature = "gecko")]
pub fn shared_font_list(&self) -> &RefPtr<structs::SharedFontList> {
match *self {
FontFamilyList::SharedFontList(ref r) => r,
FontFamilyList::Generic(t) => {
unsafe {
// TODO(heycam): Should really add StaticRefPtr sugar.
let index = t as usize;
mem::transmute::<
&structs::StaticRefPtr<structs::SharedFontList>,
&RefPtr<structs::SharedFontList>,
>(&structs::SharedFontList_sSingleGenerics[index])
}
},
}
}
}
/// Iterator of FontFamily
#[cfg(feature = "gecko")]
pub struct FontFamilyNameIter<'a> {
names: &'a structs::nsTArray<structs::FontFamilyName>,
cur: usize,
}
#[cfg(feature = "gecko")]
impl<'a> Iterator for FontFamilyNameIter<'a> {
type Item = SingleFontFamily;
fn next(&mut self) -> Option<Self::Item> {
if self.cur < self.names.len() {
let item = SingleFontFamily::from_font_family_name(&self.names[self.cur]);
self.cur += 1;
Some(item)
} else {
None
}
}
}
/// Preserve the readability of text when font fallback occurs

View File

@ -4,8 +4,6 @@
//! Specified values for font properties
#[cfg(feature = "gecko")]
use crate::gecko_bindings::bindings;
use crate::parser::{Parse, ParserContext};
use crate::values::computed::font::{FamilyName, FontFamilyList, FontStyleAngle, SingleFontFamily};
use crate::values::computed::{font as computed, Length, NonNegativeLength};
@ -22,7 +20,7 @@ use crate::values::CustomIdent;
use crate::Atom;
use cssparser::{Parser, Token};
#[cfg(feature = "gecko")]
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps, MallocUnconditionalSizeOf};
use std::fmt::{self, Write};
use style_traits::values::SequenceWriter;
use style_traits::{CssWriter, KeywordsCollectFn, ParseError};
@ -664,9 +662,10 @@ impl FontFamily {
/// Parse a specified font-family value
pub fn parse_specified<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
let values = input.parse_comma_separated(SingleFontFamily::parse)?;
Ok(FontFamily::Values(FontFamilyList::new(
values.into_boxed_slice(),
)))
Ok(FontFamily::Values(FontFamilyList {
list: crate::ArcSlice::from_iter(values.into_iter()),
fallback: computed::GenericFontFamily::None,
}))
}
}
@ -675,8 +674,8 @@ impl ToComputedValue for FontFamily {
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
match *self {
FontFamily::Values(ref v) => computed::FontFamily {
families: v.clone(),
FontFamily::Values(ref list) => computed::FontFamily {
families: list.clone(),
is_system_font: false,
},
FontFamily::System(_) => self.compute_system(context),
@ -690,18 +689,12 @@ impl ToComputedValue for FontFamily {
#[cfg(feature = "gecko")]
impl MallocSizeOf for FontFamily {
fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
match *self {
FontFamily::Values(ref v) => {
// Although a SharedFontList object is refcounted, we always
// attribute its size to the specified value, as long as it's
// not a value in SharedFontList::sSingleGenerics.
if matches!(v, FontFamilyList::SharedFontList(_)) {
let ptr = v.shared_font_list().get();
unsafe { bindings::Gecko_SharedFontList_SizeOfIncludingThis(ptr) }
} else {
0
}
// Although the family list is refcounted, we always attribute
// its size to the specified value.
v.list.unconditional_size_of(ops)
},
FontFamily::System(_) => 0,
}
@ -880,10 +873,10 @@ impl FontSizeKeyword {
static FONT_SIZE_FACTORS: [i32; 8] = [60, 75, 89, 100, 120, 150, 200, 300];
let ref gecko_font = cx.style().get_font().gecko();
let generic = gecko_font.mFont.family.families.single_generic().unwrap_or(computed::GenericFontFamily::None);
let base_size = unsafe {
Atom::with(gecko_font.mLanguage.mRawPtr, |atom| {
cx.font_metrics_provider
.get_size(atom, gecko_font.mGenericID)
cx.font_metrics_provider.get_size(atom, generic)
})
};

View File

@ -11,6 +11,8 @@ use std::ops::Deref;
use std::ptr::NonNull;
use std::{iter, mem};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps, MallocUnconditionalSizeOf};
/// A canary that we stash in ArcSlices.
///
/// Given we cannot use a zero-sized-type for the header, since well, C++
@ -135,6 +137,22 @@ impl<T> ArcSlice<T> {
std::mem::forget(empty);
ptr as *mut _
}
/// Returns whether there's only one reference to this ArcSlice.
pub fn is_unique(&self) -> bool {
self.0.with_arc(|arc| arc.is_unique())
}
}
impl<T: MallocSizeOf> MallocUnconditionalSizeOf for ArcSlice<T> {
#[allow(unsafe_code)]
fn unconditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
let mut size = unsafe { ops.malloc_size_of(self.0.heap_ptr()) };
for el in self.iter() {
size += el.size_of(ops);
}
size
}
}
/// The inner pointer of an ArcSlice<T>, to be sent via FFI.

View File

@ -97,6 +97,7 @@ include = [
"FontFaceSourceListComponent",
"FontLanguageOverride",
"GenericFontFamily",
"FontFamily",
"FontFamilyNameSyntax",
"OverflowWrap",
"TimingFunction",
@ -241,7 +242,6 @@ renaming_overrides_prefixing = true
"nsIURI" = "nsIURI"
"imgRequestProxy" = "imgRequestProxy"
"nsCompatibility" = "nsCompatibility"
"SharedFontList" = "SharedFontList"
"nsSimpleContentList" = "nsSimpleContentList"
"nsACString" = "nsACString"
"nsAString" = "nsAString"
@ -861,3 +861,17 @@ renaming_overrides_prefixing = true
return {true, StylePreferredRatio<N>::None()};
}
"""
"FontFamilyList" = """
// Whether the `fallback` generic is already on the family list.
inline bool ContainsFallback() const;
static StyleFontFamilyList WithOneUnquotedFamily(const nsACString&);
// Constructs a font family list with a list of names.
static StyleFontFamilyList WithNames(nsTArray<StyleSingleFontFamily>&&);
"""
"SingleFontFamily" = """
static StyleSingleFontFamily Parse(const nsACString& aName);
void AppendToString(nsACString& aFamily, bool aIncludeQuotes = true) const;
bool IsNamedFamily(const nsAString&) const;
"""

View File

@ -134,6 +134,7 @@ use style::traversal_flags::{self, TraversalFlags};
use style::use_counters::UseCounters;
use style::values::animated::{Animate, Procedure, ToAnimatedZero};
use style::values::computed::{self, Context, ToComputedValue};
use style::values::computed::font::{FontFamilyList, FontFamily, GenericFontFamily};
use style::values::distance::ComputeSquaredDistance;
use style::values::specified::gecko::IntersectionObserverRootMargin;
use style::values::specified::source_size_list::SourceSizeList;
@ -6759,13 +6760,12 @@ pub extern "C" fn Servo_ParseTransformIntoMatrix(
pub unsafe extern "C" fn Servo_ParseFontShorthandForMatching(
value: &nsACString,
data: *mut URLExtraData,
family: &mut structs::RefPtr<structs::SharedFontList>,
family: &mut FontFamilyList,
style: &mut ComputedFontStyleDescriptor,
stretch: &mut f32,
weight: &mut f32,
) -> bool {
use style::properties::shorthands::font;
use style::values::computed::font::FontFamilyList;
use style::values::computed::font::FontWeight as ComputedFontWeight;
use style::values::generics::font::FontStyle as GenericFontStyle;
use style::values::specified::font::{
@ -6793,8 +6793,7 @@ pub unsafe extern "C" fn Servo_ParseFontShorthandForMatching(
// The system font is not acceptable, so we return false.
match font.font_family {
FontFamily::Values(FontFamilyList::SharedFontList(list)) => family.set_move(list),
FontFamily::Values(list) => family.set_move(list.shared_font_list().clone()),
FontFamily::Values(list) => *family = list,
FontFamily::System(_) => return false,
}
@ -7084,3 +7083,31 @@ pub unsafe extern "C" fn Servo_CursorKind_Parse(
Err(..) => false,
}
}
#[no_mangle]
pub extern "C" fn Servo_FontFamily_Generic(generic: GenericFontFamily) -> &'static FontFamily {
FontFamily::generic(generic)
}
#[no_mangle]
pub extern "C" fn Servo_FontFamily_ForSystemFont(name: &nsACString, out: &mut FontFamily) {
*out = FontFamily::for_system_font(&name.to_utf8());
}
#[no_mangle]
pub extern "C" fn Servo_FontFamilyList_Normalize(list: &mut FontFamilyList) {
list.normalize()
}
#[no_mangle]
pub extern "C" fn Servo_FontFamilyList_WithNames(names: &nsTArray<computed::font::SingleFontFamily>, out: &mut FontFamilyList) {
*out = FontFamilyList {
list: style_traits::arc_slice::ArcSlice::from_iter(names.iter().cloned()),
fallback: GenericFontFamily::None,
};
}
#[no_mangle]
pub extern "C" fn Servo_GenericFontFamily_Parse(input: &nsACString) -> GenericFontFamily {
GenericFontFamily::from_ident(&*input.to_utf8()).unwrap_or(GenericFontFamily::None)
}