summaryrefslogtreecommitdiffstats
path: root/gfx/thebes
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/thebes')
-rw-r--r--gfx/thebes/gfxFontConstants.h3
-rw-r--r--gfx/thebes/gfxFontFamilyList.h1
-rw-r--r--gfx/thebes/gfxPlatformFontList.cpp66
-rw-r--r--gfx/thebes/gfxPlatformFontList.h11
-rw-r--r--gfx/thebes/gfxTextRun.cpp23
-rw-r--r--gfx/thebes/gfxTextRun.h3
6 files changed, 88 insertions, 19 deletions
diff --git a/gfx/thebes/gfxFontConstants.h b/gfx/thebes/gfxFontConstants.h
index 5aa1eb0c7..3eae49ee1 100644
--- a/gfx/thebes/gfxFontConstants.h
+++ b/gfx/thebes/gfxFontConstants.h
@@ -222,13 +222,14 @@ enum {
#define NS_FONT_SUB_SUPER_SMALL_SIZE (20.0)
#define NS_FONT_SUB_SUPER_LARGE_SIZE (45.0)
-// pref lang id's for font prefs
+// pref lang ids for font prefs
enum eFontPrefLang {
#define FONT_PREF_LANG(enum_id_, str_, atom_id_) eFontPrefLang_ ## enum_id_
#include "gfxFontPrefLangList.h"
#undef FONT_PREF_LANG
, eFontPrefLang_CJKSet // special code for CJK set
+ , eFontPrefLang_Emoji // special code for emoji presentation
, eFontPrefLang_First = eFontPrefLang_Western
, eFontPrefLang_Last = eFontPrefLang_Others
, eFontPrefLang_Count = (eFontPrefLang_Last - eFontPrefLang_First + 1)
diff --git a/gfx/thebes/gfxFontFamilyList.h b/gfx/thebes/gfxFontFamilyList.h
index e240102e0..9d1a3cf49 100644
--- a/gfx/thebes/gfxFontFamilyList.h
+++ b/gfx/thebes/gfxFontFamilyList.h
@@ -38,6 +38,7 @@ enum FontFamilyType : uint32_t {
// special
eFamily_moz_variable,
eFamily_moz_fixed,
+ eFamily_moz_emoji,
eFamily_generic_first = eFamily_serif,
eFamily_generic_last = eFamily_fantasy,
diff --git a/gfx/thebes/gfxPlatformFontList.cpp b/gfx/thebes/gfxPlatformFontList.cpp
index 01394db14..06da75ee4 100644
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -869,28 +869,55 @@ gfxPlatformFontList::ResolveGenericFontNames(
nsIAtom* langGroup = GetLangGroupForPrefLang(aPrefLang);
NS_ASSERTION(langGroup, "null lang group for pref lang");
+ gfxPlatformFontList::GetFontFamiliesFromGenericFamilies(genericFamilies,
+ langGroup,
+ aGenericFamilies);
+
+#if 0 // dump out generic mappings
+ printf("%s ===> ", prefFontName.get());
+ for (uint32_t k = 0; k < aGenericFamilies->Length(); k++) {
+ if (k > 0) printf(", ");
+ printf("%s", NS_ConvertUTF16toUTF8(aGenericFamilies[k]->Name()).get());
+ }
+ printf("\n");
+#endif
+}
+
+void
+gfxPlatformFontList::ResolveEmojiFontNames(
+ nsTArray<RefPtr<gfxFontFamily>>* aGenericFamilies)
+{
+ // emoji preference has no lang name
+ AutoTArray<nsString,4> genericFamilies;
+
+ nsAutoCString prefFontListName("font.name-list.emoji");
+ gfxFontUtils::AppendPrefsFontList(prefFontListName.get(), genericFamilies);
+
+ gfxPlatformFontList::GetFontFamiliesFromGenericFamilies(genericFamilies,
+ nullptr,
+ aGenericFamilies);
+}
+
+void
+gfxPlatformFontList::GetFontFamiliesFromGenericFamilies(
+ nsTArray<nsString>& aGenericNameFamilies,
+ nsAtom* aLangGroup,
+ nsTArray<RefPtr<gfxFontFamily>>* aGenericFamilies)
+{
// lookup and add platform fonts uniquely
- for (const nsString& genericFamily : genericFamilies) {
+ for (const nsString& genericFamily : aGenericNameFamilies) {
gfxFontStyle style;
- style.language = langGroup;
+ style.language = aLangGroup;
style.systemFont = false;
AutoTArray<gfxFontFamily*,10> families;
- FindAndAddFamilies(genericFamily, &families, &style);
+ FindAndAddFamilies(genericFamily, &families, FindFamiliesFlags(0),
+ &style);
for (gfxFontFamily* f : families) {
if (!aGenericFamilies->Contains(f)) {
aGenericFamilies->AppendElement(f);
}
}
}
-
-#if 0 // dump out generic mappings
- printf("%s ===> ", prefFontName.get());
- for (uint32_t k = 0; k < aGenericFamilies->Length(); k++) {
- if (k > 0) printf(", ");
- printf("%s", NS_ConvertUTF16toUTF8(aGenericFamilies[k]->Name()).get());
- }
- printf("\n");
-#endif
}
nsTArray<RefPtr<gfxFontFamily>>*
@@ -902,6 +929,17 @@ gfxPlatformFontList::GetPrefFontsLangGroup(mozilla::FontFamilyType aGenericType,
aGenericType = eFamily_monospace;
}
+ if (aGenericType == eFamily_moz_emoji) {
+ // Emoji font has no lang
+ PrefFontList* prefFonts = mEmojiPrefFont.get();
+ if (MOZ_UNLIKELY(!prefFonts)) {
+ prefFonts = new PrefFontList;
+ ResolveEmojiFontNames(prefFonts);
+ mEmojiPrefFont.reset(prefFonts);
+ }
+ return prefFonts;
+ }
+
PrefFontList* prefFonts =
mLangGroupPrefFonts[aPrefLang][aGenericType].get();
if (MOZ_UNLIKELY(!prefFonts)) {
@@ -1180,6 +1218,10 @@ gfxPlatformFontList::AppendPrefLang(eFontPrefLang aPrefLangs[], uint32_t& aLen,
mozilla::FontFamilyType
gfxPlatformFontList::GetDefaultGeneric(eFontPrefLang aLang)
{
+ if (aLang == eFontPrefLang_Emoji) {
+ return eFamily_moz_emoji;
+ }
+
// initialize lang group pref font defaults (i.e. serif/sans-serif)
if (MOZ_UNLIKELY(mDefaultGenericsLangGroup.IsEmpty())) {
mDefaultGenericsLangGroup.AppendElements(ArrayLength(gPrefLangNames));
diff --git a/gfx/thebes/gfxPlatformFontList.h b/gfx/thebes/gfxPlatformFontList.h
index c16994d8c..c3795a072 100644
--- a/gfx/thebes/gfxPlatformFontList.h
+++ b/gfx/thebes/gfxPlatformFontList.h
@@ -380,6 +380,15 @@ protected:
eFontPrefLang aPrefLang,
nsTArray<RefPtr<gfxFontFamily>>* aGenericFamilies);
+ void
+ ResolveEmojiFontNames(nsTArray<RefPtr<gfxFontFamily>>* aGenericFamilies);
+
+ void
+ GetFontFamiliesFromGenericFamilies(
+ nsTArray<nsString>& aGenericFamilies,
+ nsAtom* aLangGroup,
+ nsTArray<RefPtr<gfxFontFamily>>* aFontFamilies);
+
virtual nsresult InitFontListForPlatform() = 0;
void ApplyWhitelist();
@@ -436,6 +445,8 @@ protected:
eFontPrefLang_First,
eFontPrefLang_Count> mLangGroupPrefFonts;
+ mozilla::UniquePtr<PrefFontList> mEmojiPrefFont;
+
// when system-wide font lookup fails for a character, cache it to skip future searches
gfxSparseBitSet mCodepointsWithNoFonts;
diff --git a/gfx/thebes/gfxTextRun.cpp b/gfx/thebes/gfxTextRun.cpp
index 6718eed01..45ea7e6d0 100644
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -45,6 +45,9 @@ using mozilla::services::GetObserverService;
static const char16_t kEllipsisChar[] = { 0x2026, 0x0 };
static const char16_t kASCIIPeriodsChar[] = { '.', '.', '.', 0x0 };
+const uint32_t kVariationSelector15 = 0xFE0E; // text presentation
+const uint32_t kVariationSelector16 = 0xFE0F; // emoji presentation
+
#ifdef DEBUG_roc
#define DEBUG_TEXT_RUN_STORAGE_METRICS
#endif
@@ -2813,7 +2816,7 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, uint32_t aNextCh,
return nullptr;
// 2. search pref fonts
- RefPtr<gfxFont> font = WhichPrefFontSupportsChar(aCh);
+ RefPtr<gfxFont> font = WhichPrefFontSupportsChar(aCh, aNextCh);
if (font) {
*aMatchType = gfxTextRange::kPrefsFallback;
return font.forget();
@@ -3081,15 +3084,25 @@ gfxFontGroup::ContainsUserFont(const gfxUserFontEntry* aUserFont)
}
already_AddRefed<gfxFont>
-gfxFontGroup::WhichPrefFontSupportsChar(uint32_t aCh)
+gfxFontGroup::WhichPrefFontSupportsChar(uint32_t aCh, uint32_t aNextCh)
{
RefPtr<gfxFont> font;
- // get the pref font list if it hasn't been set up already
- uint32_t unicodeRange = FindCharUnicodeRange(aCh);
+ eFontPrefLang charLang;
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
- eFontPrefLang charLang = pfl->GetFontPrefLangFor(unicodeRange);
+ EmojiPresentation emoji = GetEmojiPresentation(aCh);
+ if ((emoji != EmojiPresentation::TextOnly &&
+ (aNextCh == kVariationSelector16 ||
+ (emoji == EmojiPresentation::EmojiDefault &&
+ aNextCh != kVariationSelector15)))) {
+ charLang = eFontPrefLang_Emoji;
+ } else {
+ // get the pref font list if it hasn't been set up already
+ uint32_t unicodeRange = FindCharUnicodeRange(aCh);
+ charLang = pfl->GetFontPrefLangFor(unicodeRange);
+ }
+
// if the last pref font was the first family in the pref list, no need to recheck through a list of families
if (mLastPrefFont && charLang == mLastPrefLang &&
mLastPrefFirstFont && mLastPrefFont->HasCharacter(aCh)) {
diff --git a/gfx/thebes/gfxTextRun.h b/gfx/thebes/gfxTextRun.h
index 0e44456ae..c3673785c 100644
--- a/gfx/thebes/gfxTextRun.h
+++ b/gfx/thebes/gfxTextRun.h
@@ -917,7 +917,8 @@ public:
protected:
// search through pref fonts for a character, return nullptr if no matching pref font
- already_AddRefed<gfxFont> WhichPrefFontSupportsChar(uint32_t aCh);
+ already_AddRefed<gfxFont> WhichPrefFontSupportsChar(uint32_t aCh,
+ uint32_t aNextCh);
already_AddRefed<gfxFont>
WhichSystemFontSupportsChar(uint32_t aCh, uint32_t aNextCh,