Bug 1461589 - Handle font-variant-emoji during font matching. r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D147495
This commit is contained in:
Jonathan Kew 2022-10-22 09:43:49 +00:00
Родитель 89c8d6a003
Коммит 8888937e07
6 изменённых файлов: 46 добавлений и 47 удалений

Просмотреть файл

@ -3526,15 +3526,16 @@ bool CanvasRenderingContext2D::SetFontInternalDisconnected(
// TODO: For workers, should we be passing a language? Where from?
// TODO: Cache fontGroups in the Worker (use an nsFontCache?)
gfxFontGroup* fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(
nullptr, // aPresContext
list, // aFontFamilyList
&fontStyle, // aStyle
language, // aLanguage
explicitLanguage, // aExplicitLanguage
nullptr, // aTextPerf
fontFaceSetImpl, // aUserFontSet
1.0); // aDevToCssSize
gfxFontGroup* fontGroup =
new gfxFontGroup(nullptr, // aPresContext
list, // aFontFamilyList
&fontStyle, // aStyle
language, // aLanguage
explicitLanguage, // aExplicitLanguage
nullptr, // aTextPerf
fontFaceSetImpl, // aUserFontSet
1.0, // aDevToCssSize
StyleFontVariantEmoji::Normal);
CurrentState().fontGroup = fontGroup;
SerializeFontForCanvas(list, fontStyle, CurrentState().font);
CurrentState().fontFont = nsFont(StyleFontFamily{list, false, false},
@ -4327,10 +4328,10 @@ gfxFontGroup* CanvasRenderingContext2D::GetCurrentFontStyle() {
gfxFloat devToCssSize = gfxFloat(perDevPixel) / gfxFloat(perCSSPixel);
const auto* sans =
Servo_FontFamily_Generic(StyleGenericFontFamily::SansSerif);
fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(
fontGroup = new gfxFontGroup(
presContext, sans->families, &style, language, explicitLanguage,
presContext ? presContext->GetTextPerfMetrics() : nullptr, nullptr,
devToCssSize);
devToCssSize, StyleFontVariantEmoji::Normal);
if (fontGroup) {
CurrentState().font = kDefaultFontStyle;
} else {

Просмотреть файл

@ -138,9 +138,9 @@ nsFontMetrics::nsFontMetrics(const nsFont& aFont, const Params& aParams,
aFont.AddFontVariationsToStyle(&style);
gfxFloat devToCssSize = gfxFloat(mP2A) / gfxFloat(AppUnitsPerCSSPixel());
mFontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(
mFontGroup = new gfxFontGroup(
mPresContext, aFont.family.families, &style, mLanguage, mExplicitLanguage,
aParams.textPerf, aParams.userFontSet, devToCssSize);
aParams.textPerf, aParams.userFontSet, devToCssSize, aFont.variantEmoji);
}
nsFontMetrics::~nsFontMetrics() {

Просмотреть файл

@ -1846,16 +1846,6 @@ bool gfxPlatform::IsFontFormatSupported(
return true;
}
gfxFontGroup* gfxPlatform::CreateFontGroup(
nsPresContext* aPresContext, const StyleFontFamilyList& aFontFamilyList,
const gfxFontStyle* aStyle, nsAtom* aLanguage, bool aExplicitLanguage,
gfxTextPerfMetrics* aTextPerf, gfxUserFontSet* aUserFontSet,
gfxFloat aDevToCssSize) const {
return new gfxFontGroup(aPresContext, aFontFamilyList, aStyle, aLanguage,
aExplicitLanguage, aTextPerf, aUserFontSet,
aDevToCssSize);
}
gfxFontEntry* gfxPlatform::LookupLocalFont(nsPresContext* aPresContext,
const nsACString& aFontName,
WeightRange aWeightForEntry,

Просмотреть файл

@ -398,16 +398,6 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
nsAutoCString GetDefaultFontName(const nsACString& aLangGroup,
const nsACString& aGenericFamily);
/**
* Create a gfxFontGroup based on the given family list and style.
*/
gfxFontGroup* CreateFontGroup(
nsPresContext* aPresContext,
const mozilla::StyleFontFamilyList& aFontFamilyList,
const gfxFontStyle* aStyle, nsAtom* aLanguage, bool aExplicitLanguage,
gfxTextPerfMetrics* aTextPerf, gfxUserFontSet* aUserFontSet,
gfxFloat aDevToCssSize) const;
/**
* Look up a local platform font using the full font face name.
* (Needed to support @font-face src local().)

Просмотреть файл

@ -1884,7 +1884,8 @@ gfxFontGroup::gfxFontGroup(nsPresContext* aPresContext,
const gfxFontStyle* aStyle, nsAtom* aLanguage,
bool aExplicitLanguage,
gfxTextPerfMetrics* aTextPerf,
gfxUserFontSet* aUserFontSet, gfxFloat aDevToCssSize)
gfxUserFontSet* aUserFontSet, gfxFloat aDevToCssSize,
StyleFontVariantEmoji aVariantEmoji)
: mPresContext(aPresContext), // Note that aPresContext may be null!
mFamilyList(aFontFamilyList),
mStyle(*aStyle),
@ -1899,6 +1900,17 @@ gfxFontGroup::gfxFontGroup(nsPresContext* aPresContext,
mLastPrefFirstFont(false),
mSkipDrawing(false),
mExplicitLanguage(aExplicitLanguage) {
switch (aVariantEmoji) {
case StyleFontVariantEmoji::Normal:
case StyleFontVariantEmoji::Unicode:
break;
case StyleFontVariantEmoji::Text:
mEmojiPresentation = eFontPresentation::Text;
break;
case StyleFontVariantEmoji::Emoji:
mEmojiPresentation = eFontPresentation::EmojiExplicit;
break;
}
// We don't use SetUserFontSet() here, as we want to unconditionally call
// BuildFontList() rather than only do UpdateUserFonts() if it changed.
mCurrGeneration = GetGeneration();
@ -3100,24 +3112,27 @@ already_AddRefed<gfxFont> gfxFontGroup::FindFontForChar(
eFontPresentation presentation = eFontPresentation::Any;
EmojiPresentation emojiPresentation = GetEmojiPresentation(aCh);
if (emojiPresentation != TextOnly) {
// If the prefer-emoji selector is present, or if it's a default-emoji char
// and the prefer-text selector is NOT present, or if there's a skin-tone
// modifier, we specifically look for a font with a color glyph.
// If the prefer-text selector is present, we specifically look for a font
// that will provide a monochrome glyph.
// Otherwise, we'll accept either color or monochrome font-family entries,
// so that a color font can be explicitly applied via font-family even to
// characters that are not inherently emoji-style.
// Default presentation from the font-variant-emoji property.
presentation = mEmojiPresentation;
// If the prefer-emoji selector is present, or if it's a default-emoji
// char and the prefer-text selector is NOT present, or if there's a
// skin-tone modifier, we specifically look for a font with a color
// glyph.
// If the prefer-text selector is present, we specifically look for a
// font that will provide a monochrome glyph.
// Otherwise, we'll accept either color or monochrome font-family
// entries, so that a color font can be explicitly applied via font-
// family even to characters that are not inherently emoji-style.
if (aNextCh == kVariationSelector16 ||
(aNextCh >= kEmojiSkinToneFirst && aNextCh <= kEmojiSkinToneLast)) {
// Emoji presentation is explicitly requested by a variation selector or
// the presence of a skin-tone codepoint.
// Emoji presentation is explicitly requested by a variation selector
// or the presence of a skin-tone codepoint.
presentation = eFontPresentation::EmojiExplicit;
} else if (emojiPresentation == EmojiPresentation::EmojiDefault &&
aNextCh != kVariationSelector15) {
// Emoji presentation is the default for this Unicode character. but we
// will allow an explicitly-specified webfont to apply to it, regardless
// of its glyph type.
// will allow an explicitly-specified webfont to apply to it,
// regardless of its glyph type.
presentation = eFontPresentation::EmojiDefault;
} else if (aNextCh == kVariationSelector15) {
// Text presentation is explicitly requested.

Просмотреть файл

@ -936,7 +936,8 @@ class gfxFontGroup final : public gfxTextRunFactory {
const mozilla::StyleFontFamilyList& aFontFamilyList,
const gfxFontStyle* aStyle, nsAtom* aLanguage,
bool aExplicitLanguage, gfxTextPerfMetrics* aTextPerf,
gfxUserFontSet* aUserFontSet, gfxFloat aDevToCssSize);
gfxUserFontSet* aUserFontSet, gfxFloat aDevToCssSize,
StyleFontVariantEmoji aVariantEmoji);
virtual ~gfxFontGroup();
@ -1420,6 +1421,8 @@ class gfxFontGroup final : public gfxTextRunFactory {
bool mExplicitLanguage; // Does mLanguage come from an explicit attribute?
eFontPresentation mEmojiPresentation = eFontPresentation::Any;
// Generic font family used to select among font prefs during fallback.
mozilla::StyleGenericFontFamily mFallbackGeneric =
mozilla::StyleGenericFontFamily::None;