зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 0cad1ef724ee (bug 1371386) for causing failures in emoji-fallback-3.html
CLOSED TREE
This commit is contained in:
Родитель
77abfc0039
Коммит
b162701621
|
@ -33,8 +33,7 @@ static double WSSDistance(const Face* aFace, const gfxFontStyle& aStyle) {
|
||||||
// weight/style/stretch priority: stretch >> style >> weight
|
// weight/style/stretch priority: stretch >> style >> weight
|
||||||
// so we multiply the stretch and style values to make them dominate
|
// so we multiply the stretch and style values to make them dominate
|
||||||
// the result
|
// the result
|
||||||
return stretchDist * kStretchFactor + styleDist * kStyleFactor +
|
return stretchDist * 1.0e8 + styleDist * 1.0e4 + weightDist;
|
||||||
weightDist * kWeightFactor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void* Pointer::ToPtr(FontList* aFontList) const {
|
void* Pointer::ToPtr(FontList* aFontList) const {
|
||||||
|
@ -399,21 +398,6 @@ void Family::SearchAllFontsForChar(FontList* aList,
|
||||||
if (!charmap && !fe->HasCharacter(aMatchData->mCh)) {
|
if (!charmap && !fe->HasCharacter(aMatchData->mCh)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (aMatchData->mPresentation != eFontPresentation::Any) {
|
|
||||||
gfxFont* font = fe->FindOrMakeFont(&aMatchData->mStyle);
|
|
||||||
if (!font) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bool hasColorGlyph =
|
|
||||||
font->HasColorGlyphFor(aMatchData->mCh, aMatchData->mNextCh);
|
|
||||||
if (hasColorGlyph !=
|
|
||||||
(aMatchData->mPresentation == eFontPresentation::Emoji)) {
|
|
||||||
distance += kPresentationMismatch;
|
|
||||||
if (distance >= aMatchData->mMatchDistance) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
aMatchData->mBestMatch = fe;
|
aMatchData->mBestMatch = fe;
|
||||||
aMatchData->mMatchDistance = distance;
|
aMatchData->mMatchDistance = distance;
|
||||||
aMatchData->mMatchedSharedFamily = this;
|
aMatchData->mMatchedSharedFamily = this;
|
||||||
|
|
|
@ -156,14 +156,14 @@ static bool IsJapaneseLocale() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfxAndroidPlatform::GetCommonFallbackFonts(
|
void gfxAndroidPlatform::GetCommonFallbackFonts(
|
||||||
uint32_t aCh, Script aRunScript, eFontPresentation aPresentation,
|
uint32_t aCh, uint32_t aNextCh, Script aRunScript,
|
||||||
nsTArray<const char*>& aFontList) {
|
nsTArray<const char*>& aFontList) {
|
||||||
static const char kDroidSansJapanese[] = "Droid Sans Japanese";
|
static const char kDroidSansJapanese[] = "Droid Sans Japanese";
|
||||||
static const char kMotoyaLMaru[] = "MotoyaLMaru";
|
static const char kMotoyaLMaru[] = "MotoyaLMaru";
|
||||||
static const char kNotoSansCJKJP[] = "Noto Sans CJK JP";
|
static const char kNotoSansCJKJP[] = "Noto Sans CJK JP";
|
||||||
static const char kNotoColorEmoji[] = "Noto Color Emoji";
|
static const char kNotoColorEmoji[] = "Noto Color Emoji";
|
||||||
|
|
||||||
if (aPresentation == eFontPresentation::Emoji) {
|
if (ShouldPreferEmojiFont(aCh, aNextCh)) {
|
||||||
aFontList.AppendElement(kNotoColorEmoji);
|
aFontList.AppendElement(kNotoColorEmoji);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,7 @@ class gfxAndroidPlatform final : public gfxPlatform {
|
||||||
void ReadSystemFontList(
|
void ReadSystemFontList(
|
||||||
nsTArray<mozilla::dom::SystemFontListEntry>* aFontList) override;
|
nsTArray<mozilla::dom::SystemFontListEntry>* aFontList) override;
|
||||||
|
|
||||||
void GetCommonFallbackFonts(uint32_t aCh, Script aRunScript,
|
void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, Script aRunScript,
|
||||||
eFontPresentation aPresentation,
|
|
||||||
nsTArray<const char*>& aFontList) override;
|
nsTArray<const char*>& aFontList) override;
|
||||||
|
|
||||||
bool FontHintingEnabled() override;
|
bool FontHintingEnabled() override;
|
||||||
|
|
|
@ -2409,40 +2409,6 @@ bool gfxFont::RenderColorGlyph(DrawTarget* aDrawTarget, gfxContext* aContext,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gfxFont::HasColorGlyphFor(uint32_t aCh, uint32_t aNextCh) {
|
|
||||||
// Bitmap fonts are assumed to provide "color" glyphs for all supported chars.
|
|
||||||
gfxFontEntry* fe = GetFontEntry();
|
|
||||||
if (fe->HasColorBitmapTable()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Use harfbuzz shaper to look up the default glyph ID for the character.
|
|
||||||
if (!mHarfBuzzShaper) {
|
|
||||||
mHarfBuzzShaper = MakeUnique<gfxHarfBuzzShaper>(this);
|
|
||||||
}
|
|
||||||
auto* shaper = static_cast<gfxHarfBuzzShaper*>(mHarfBuzzShaper.get());
|
|
||||||
if (!shaper->Initialize()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
uint32_t gid = 0;
|
|
||||||
if (gfxFontUtils::IsVarSelector(aNextCh)) {
|
|
||||||
gid = shaper->GetVariationGlyph(aCh, aNextCh);
|
|
||||||
}
|
|
||||||
if (!gid) {
|
|
||||||
gid = shaper->GetNominalGlyph(aCh);
|
|
||||||
}
|
|
||||||
if (!gid) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Check if there is a COLR/CPAL or SVG glyph for this ID.
|
|
||||||
if (fe->TryGetColorGlyphs() && fe->HasColorLayersForGlyph(gid)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (fe->TryGetSVGData(this) && fe->HasSVGGlyph(gid)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void UnionRange(gfxFloat aX, gfxFloat* aDestMin, gfxFloat* aDestMax) {
|
static void UnionRange(gfxFloat aX, gfxFloat* aDestMin, gfxFloat* aDestMax) {
|
||||||
*aDestMin = std::min(*aDestMin, aX);
|
*aDestMin = std::min(*aDestMin, aX);
|
||||||
*aDestMax = std::max(*aDestMax, aX);
|
*aDestMax = std::max(*aDestMax, aX);
|
||||||
|
|
|
@ -1864,8 +1864,6 @@ class gfxFont {
|
||||||
// glyphs. This does not add a reference to the returned font.
|
// glyphs. This does not add a reference to the returned font.
|
||||||
gfxFont* GetSubSuperscriptFont(int32_t aAppUnitsPerDevPixel);
|
gfxFont* GetSubSuperscriptFont(int32_t aAppUnitsPerDevPixel);
|
||||||
|
|
||||||
bool HasColorGlyphFor(uint32_t aCh, uint32_t aNextCh);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual const Metrics& GetHorizontalMetrics() = 0;
|
virtual const Metrics& GetHorizontalMetrics() = 0;
|
||||||
|
|
||||||
|
|
|
@ -1556,8 +1556,7 @@ static inline double WeightStyleStretchDistance(
|
||||||
// weight/style/stretch priority: stretch >> style >> weight
|
// weight/style/stretch priority: stretch >> style >> weight
|
||||||
// so we multiply the stretch and style values to make them dominate
|
// so we multiply the stretch and style values to make them dominate
|
||||||
// the result
|
// the result
|
||||||
return stretchDist * kStretchFactor + styleDist * kStyleFactor +
|
return stretchDist * 1.0e8 + styleDist * 1.0e4 + weightDist;
|
||||||
weightDist * kWeightFactor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfxFontFamily::FindAllFontsForStyle(
|
void gfxFontFamily::FindAllFontsForStyle(
|
||||||
|
@ -1795,18 +1794,6 @@ void gfxFontFamily::FindFontForChar(GlobalFontMatch* aMatchData) {
|
||||||
|
|
||||||
fe = e;
|
fe = e;
|
||||||
distance = WeightStyleStretchDistance(fe, aMatchData->mStyle);
|
distance = WeightStyleStretchDistance(fe, aMatchData->mStyle);
|
||||||
if (aMatchData->mPresentation != eFontPresentation::Any) {
|
|
||||||
RefPtr<gfxFont> font = fe->FindOrMakeFont(&aMatchData->mStyle);
|
|
||||||
if (!font) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bool hasColorGlyph =
|
|
||||||
font->HasColorGlyphFor(aMatchData->mCh, aMatchData->mNextCh);
|
|
||||||
if (hasColorGlyph !=
|
|
||||||
(aMatchData->mPresentation == eFontPresentation::Emoji)) {
|
|
||||||
distance += kPresentationMismatch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1815,8 +1802,7 @@ void gfxFontFamily::FindFontForChar(GlobalFontMatch* aMatchData) {
|
||||||
// If style/weight/stretch was not Normal, see if we can
|
// If style/weight/stretch was not Normal, see if we can
|
||||||
// fall back to a next-best face (e.g. Arial Black -> Bold,
|
// fall back to a next-best face (e.g. Arial Black -> Bold,
|
||||||
// or Arial Narrow -> Regular).
|
// or Arial Narrow -> Regular).
|
||||||
GlobalFontMatch data(aMatchData->mCh, aMatchData->mNextCh,
|
GlobalFontMatch data(aMatchData->mCh, aMatchData->mStyle);
|
||||||
aMatchData->mStyle, aMatchData->mPresentation);
|
|
||||||
SearchAllFontsForChar(&data);
|
SearchAllFontsForChar(&data);
|
||||||
if (!data.mBestMatch) {
|
if (!data.mBestMatch) {
|
||||||
return;
|
return;
|
||||||
|
@ -1850,18 +1836,6 @@ void gfxFontFamily::SearchAllFontsForChar(GlobalFontMatch* aMatchData) {
|
||||||
gfxFontEntry* fe = mAvailableFonts[i];
|
gfxFontEntry* fe = mAvailableFonts[i];
|
||||||
if (fe && fe->HasCharacter(aMatchData->mCh)) {
|
if (fe && fe->HasCharacter(aMatchData->mCh)) {
|
||||||
float distance = WeightStyleStretchDistance(fe, aMatchData->mStyle);
|
float distance = WeightStyleStretchDistance(fe, aMatchData->mStyle);
|
||||||
if (aMatchData->mPresentation != eFontPresentation::Any) {
|
|
||||||
RefPtr<gfxFont> font = fe->FindOrMakeFont(&aMatchData->mStyle);
|
|
||||||
if (!font) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bool hasColorGlyph =
|
|
||||||
font->HasColorGlyphFor(aMatchData->mCh, aMatchData->mNextCh);
|
|
||||||
if (hasColorGlyph !=
|
|
||||||
(aMatchData->mPresentation == eFontPresentation::Emoji)) {
|
|
||||||
distance += kPresentationMismatch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (distance < aMatchData->mMatchDistance ||
|
if (distance < aMatchData->mMatchDistance ||
|
||||||
(distance == aMatchData->mMatchDistance &&
|
(distance == aMatchData->mMatchDistance &&
|
||||||
Compare(fe->Name(), aMatchData->mBestMatch->Name()) > 0)) {
|
Compare(fe->Name(), aMatchData->mBestMatch->Name()) > 0)) {
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include "gfxFontFeatures.h"
|
#include "gfxFontFeatures.h"
|
||||||
#include "gfxFontUtils.h"
|
#include "gfxFontUtils.h"
|
||||||
#include "gfxFontVariations.h"
|
#include "gfxFontVariations.h"
|
||||||
#include "gfxPlatform.h"
|
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsTHashtable.h"
|
#include "nsTHashtable.h"
|
||||||
#include "mozilla/HashFunctions.h"
|
#include "mozilla/HashFunctions.h"
|
||||||
|
@ -255,15 +254,6 @@ class gfxFontEntry {
|
||||||
const mozilla::gfx::DeviceColor& aDefaultColor,
|
const mozilla::gfx::DeviceColor& aDefaultColor,
|
||||||
nsTArray<uint16_t>& layerGlyphs,
|
nsTArray<uint16_t>& layerGlyphs,
|
||||||
nsTArray<mozilla::gfx::DeviceColor>& layerColors);
|
nsTArray<mozilla::gfx::DeviceColor>& layerColors);
|
||||||
bool HasColorLayersForGlyph(uint32_t aGlyphId) {
|
|
||||||
MOZ_ASSERT(mCOLR);
|
|
||||||
return gfxFontUtils::HasColorLayersForGlyph(mCOLR, aGlyphId);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HasColorBitmapTable() {
|
|
||||||
return HasFontTable(TRUETYPE_TAG('C', 'B', 'D', 'T')) ||
|
|
||||||
HasFontTable(TRUETYPE_TAG('s', 'b', 'i', 'x'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Access to raw font table data (needed for Harfbuzz):
|
// Access to raw font table data (needed for Harfbuzz):
|
||||||
// returns a pointer to data owned by the fontEntry or the OS,
|
// returns a pointer to data owned by the fontEntry or the OS,
|
||||||
|
@ -762,23 +752,17 @@ inline bool gfxFontEntry::SupportsBold() {
|
||||||
|
|
||||||
// used when iterating over all fonts looking for a match for a given character
|
// used when iterating over all fonts looking for a match for a given character
|
||||||
struct GlobalFontMatch {
|
struct GlobalFontMatch {
|
||||||
GlobalFontMatch(uint32_t aCharacter, uint32_t aNextCh,
|
GlobalFontMatch(const uint32_t aCharacter, const gfxFontStyle& aStyle)
|
||||||
const gfxFontStyle& aStyle, eFontPresentation aPresentation)
|
: mStyle(aStyle), mCh(aCharacter) {}
|
||||||
: mStyle(aStyle),
|
|
||||||
mCh(aCharacter),
|
|
||||||
mNextCh(aNextCh),
|
|
||||||
mPresentation(aPresentation) {}
|
|
||||||
|
|
||||||
RefPtr<gfxFontEntry> mBestMatch; // current best match
|
RefPtr<gfxFontEntry> mBestMatch; // current best match
|
||||||
RefPtr<gfxFontFamily> mMatchedFamily; // the family it belongs to
|
RefPtr<gfxFontFamily> mMatchedFamily; // the family it belongs to
|
||||||
mozilla::fontlist::Family* mMatchedSharedFamily = nullptr;
|
mozilla::fontlist::Family* mMatchedSharedFamily = nullptr;
|
||||||
const gfxFontStyle& mStyle; // style to match
|
const gfxFontStyle& mStyle; // style to match
|
||||||
const uint32_t mCh; // codepoint to be matched
|
const uint32_t mCh; // codepoint to be matched
|
||||||
const uint32_t mNextCh; // following codepoint (or zero)
|
uint32_t mCount = 0; // number of fonts matched
|
||||||
eFontPresentation mPresentation;
|
uint32_t mCmapsTested = 0; // number of cmaps tested
|
||||||
uint32_t mCount = 0; // number of fonts matched
|
float mMatchDistance = INFINITY; // metric indicating closest match
|
||||||
uint32_t mCmapsTested = 0; // number of cmaps tested
|
|
||||||
double mMatchDistance = INFINITY; // metric indicating closest match
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Installation status (base system / langpack / user-installed) may determine
|
// Installation status (base system / langpack / user-installed) may determine
|
||||||
|
|
|
@ -1722,16 +1722,6 @@ bool gfxFontUtils::GetColorGlyphLayers(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gfxFontUtils::HasColorLayersForGlyph(hb_blob_t* aCOLR, uint32_t aGlyphId) {
|
|
||||||
unsigned int blobLength;
|
|
||||||
const COLRHeader* colr =
|
|
||||||
reinterpret_cast<const COLRHeader*>(hb_blob_get_data(aCOLR, &blobLength));
|
|
||||||
MOZ_ASSERT(colr, "Cannot get COLR raw data");
|
|
||||||
MOZ_ASSERT(blobLength, "Found COLR data, but length is 0");
|
|
||||||
|
|
||||||
return LookForBaseGlyphRecord(colr, aGlyphId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gfxFontUtils::GetVariationData(
|
void gfxFontUtils::GetVariationData(
|
||||||
gfxFontEntry* aFontEntry, nsTArray<gfxFontVariationAxis>* aAxes,
|
gfxFontEntry* aFontEntry, nsTArray<gfxFontVariationAxis>* aAxes,
|
||||||
nsTArray<gfxFontVariationInstance>* aInstances) {
|
nsTArray<gfxFontVariationInstance>* aInstances) {
|
||||||
|
|
|
@ -1159,7 +1159,6 @@ class gfxFontUtils {
|
||||||
const mozilla::gfx::DeviceColor& aDefaultColor,
|
const mozilla::gfx::DeviceColor& aDefaultColor,
|
||||||
nsTArray<uint16_t>& aGlyphs,
|
nsTArray<uint16_t>& aGlyphs,
|
||||||
nsTArray<mozilla::gfx::DeviceColor>& aColors);
|
nsTArray<mozilla::gfx::DeviceColor>& aColors);
|
||||||
static bool HasColorLayersForGlyph(hb_blob_t* aCOLR, uint32_t aGlyphId);
|
|
||||||
|
|
||||||
// Helper used to implement gfxFontEntry::GetVariation{Axes,Instances} for
|
// Helper used to implement gfxFontEntry::GetVariation{Axes,Instances} for
|
||||||
// platforms where the native font APIs don't provide the info we want
|
// platforms where the native font APIs don't provide the info we want
|
||||||
|
@ -1205,16 +1204,6 @@ class gfxFontUtils {
|
||||||
static const mozilla::Encoding* gMSFontNameCharsets[];
|
static const mozilla::Encoding* gMSFontNameCharsets[];
|
||||||
};
|
};
|
||||||
|
|
||||||
// Factors used to weight the distances between the available and target font
|
|
||||||
// properties during font-matching. These ensure that we respect the CSS-fonts
|
|
||||||
// requirement that font-stretch >> font-style >> font-weight; and in addition,
|
|
||||||
// a mismatch between the desired and actual glyph presentation (emoji vs text)
|
|
||||||
// will take precedence over any of the style attributes.
|
|
||||||
constexpr double kPresentationMismatch = 1.0e12;
|
|
||||||
constexpr double kStretchFactor = 1.0e8;
|
|
||||||
constexpr double kStyleFactor = 1.0e4;
|
|
||||||
constexpr double kWeightFactor = 1.0e0;
|
|
||||||
|
|
||||||
// style distance ==> [0,500]
|
// style distance ==> [0,500]
|
||||||
static inline double StyleDistance(const mozilla::SlantStyleRange& aRange,
|
static inline double StyleDistance(const mozilla::SlantStyleRange& aRange,
|
||||||
mozilla::FontSlantStyle aTargetStyle) {
|
mozilla::FontSlantStyle aTargetStyle) {
|
||||||
|
|
|
@ -96,10 +96,6 @@ enum eGfxLog {
|
||||||
eGfxLog_textperf = 5
|
eGfxLog_textperf = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
// Used during font matching to express a preference, if any, for whether
|
|
||||||
// to use a font that will present a color or monochrome glyph.
|
|
||||||
enum class eFontPresentation : uint8_t { Any = 0, Text = 1, Emoji = 2 };
|
|
||||||
|
|
||||||
// when searching through pref langs, max number of pref langs
|
// when searching through pref langs, max number of pref langs
|
||||||
const uint32_t kMaxLenPrefLangList = 32;
|
const uint32_t kMaxLenPrefLangList = 32;
|
||||||
|
|
||||||
|
@ -479,8 +475,8 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
|
||||||
|
|
||||||
// returns a list of commonly used fonts for a given character
|
// returns a list of commonly used fonts for a given character
|
||||||
// these are *possible* matches, no cmap-checking is done at this level
|
// these are *possible* matches, no cmap-checking is done at this level
|
||||||
virtual void GetCommonFallbackFonts(uint32_t /*aCh*/, Script /*aRunScript*/,
|
virtual void GetCommonFallbackFonts(uint32_t /*aCh*/, uint32_t /*aNextCh*/,
|
||||||
eFontPresentation /*aPresentation*/,
|
Script /*aRunScript*/,
|
||||||
nsTArray<const char*>& /*aFontList*/) {
|
nsTArray<const char*>& /*aFontList*/) {
|
||||||
// platform-specific override, by default do nothing
|
// platform-specific override, by default do nothing
|
||||||
}
|
}
|
||||||
|
|
|
@ -863,19 +863,20 @@ void gfxPlatformFontList::GetFontFamilyList(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxFont* gfxPlatformFontList::SystemFindFontForChar(
|
gfxFontEntry* gfxPlatformFontList::SystemFindFontForChar(
|
||||||
uint32_t aCh, uint32_t aNextCh, Script aRunScript,
|
uint32_t aCh, uint32_t aNextCh, Script aRunScript,
|
||||||
eFontPresentation aPresentation, const gfxFontStyle* aStyle,
|
const gfxFontStyle* aStyle, FontVisibility* aVisibility,
|
||||||
FontVisibility* aVisibility, FontMatchingStats* aFontMatchingStats) {
|
FontMatchingStats* aFontMatchingStats) {
|
||||||
MOZ_ASSERT(!mCodepointsWithNoFonts.test(aCh),
|
MOZ_ASSERT(!mCodepointsWithNoFonts.test(aCh),
|
||||||
"don't call for codepoints already known to be unsupported");
|
"don't call for codepoints already known to be unsupported");
|
||||||
|
|
||||||
|
gfxFontEntry* fontEntry = nullptr;
|
||||||
|
|
||||||
// Try to short-circuit font fallback for U+FFFD, used to represent
|
// Try to short-circuit font fallback for U+FFFD, used to represent
|
||||||
// encoding errors: just use cached family from last time U+FFFD was seen.
|
// encoding errors: just use cached family from last time U+FFFD was seen.
|
||||||
// This helps speed up pages with lots of encoding errors, binary-as-text,
|
// This helps speed up pages with lots of encoding errors, binary-as-text,
|
||||||
// etc.
|
// etc.
|
||||||
if (aCh == 0xFFFD) {
|
if (aCh == 0xFFFD) {
|
||||||
gfxFontEntry* fontEntry = nullptr;
|
|
||||||
if (mReplacementCharFallbackFamily.mIsShared &&
|
if (mReplacementCharFallbackFamily.mIsShared &&
|
||||||
mReplacementCharFallbackFamily.mShared) {
|
mReplacementCharFallbackFamily.mShared) {
|
||||||
fontlist::Face* face =
|
fontlist::Face* face =
|
||||||
|
@ -896,7 +897,7 @@ gfxFont* gfxPlatformFontList::SystemFindFontForChar(
|
||||||
// this should never fail, as we must have found U+FFFD in order to set
|
// this should never fail, as we must have found U+FFFD in order to set
|
||||||
// mReplacementCharFallbackFamily at all, but better play it safe
|
// mReplacementCharFallbackFamily at all, but better play it safe
|
||||||
if (fontEntry && fontEntry->HasCharacter(aCh)) {
|
if (fontEntry && fontEntry->HasCharacter(aCh)) {
|
||||||
return fontEntry->FindOrMakeFont(aStyle);
|
return fontEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -905,35 +906,15 @@ gfxFont* gfxPlatformFontList::SystemFindFontForChar(
|
||||||
// search commonly available fonts
|
// search commonly available fonts
|
||||||
bool common = true;
|
bool common = true;
|
||||||
FontFamily fallbackFamily;
|
FontFamily fallbackFamily;
|
||||||
gfxFont* candidate = CommonFontFallback(
|
fontEntry =
|
||||||
aCh, aNextCh, aRunScript, aPresentation, aStyle, fallbackFamily);
|
CommonFontFallback(aCh, aNextCh, aRunScript, aStyle, fallbackFamily);
|
||||||
gfxFont* font = nullptr;
|
|
||||||
if (candidate) {
|
|
||||||
if (aPresentation == eFontPresentation::Any) {
|
|
||||||
font = candidate;
|
|
||||||
} else {
|
|
||||||
bool hasColorGlyph = candidate->HasColorGlyphFor(aCh, aNextCh);
|
|
||||||
if (hasColorGlyph == (aPresentation == eFontPresentation::Emoji)) {
|
|
||||||
font = candidate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we didn't find a common font, or it was not the preferred type (color
|
// if didn't find a font, do system-wide fallback (except for specials)
|
||||||
// or monochrome), do system-wide fallback (except for specials).
|
|
||||||
uint32_t cmapCount = 0;
|
uint32_t cmapCount = 0;
|
||||||
if (!font) {
|
if (!fontEntry) {
|
||||||
common = false;
|
common = false;
|
||||||
font = GlobalFontFallback(aCh, aNextCh, aRunScript, aPresentation, aStyle,
|
fontEntry = GlobalFontFallback(aCh, aRunScript, aStyle, cmapCount,
|
||||||
cmapCount, fallbackFamily, aFontMatchingStats);
|
fallbackFamily, aFontMatchingStats);
|
||||||
// If the font we found doesn't match the requested type, and we also found
|
|
||||||
// a candidate above, prefer that one.
|
|
||||||
if (font && aPresentation != eFontPresentation::Any && candidate) {
|
|
||||||
bool hasColorGlyph = font->HasColorGlyphFor(aCh, aNextCh);
|
|
||||||
if (hasColorGlyph != (aPresentation == eFontPresentation::Emoji)) {
|
|
||||||
font = candidate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
TimeDuration elapsed = TimeStamp::Now() - start;
|
TimeDuration elapsed = TimeStamp::Now() - start;
|
||||||
|
|
||||||
|
@ -946,12 +927,12 @@ gfxFont* gfxPlatformFontList::SystemFindFontForChar(
|
||||||
"script: %d match: [%s]"
|
"script: %d match: [%s]"
|
||||||
" time: %dus cmaps: %d\n",
|
" time: %dus cmaps: %d\n",
|
||||||
(common ? "common" : "global"), aCh, static_cast<int>(script),
|
(common ? "common" : "global"), aCh, static_cast<int>(script),
|
||||||
(font ? font->GetFontEntry()->Name().get() : "<none>"),
|
(fontEntry ? fontEntry->Name().get() : "<none>"),
|
||||||
int32_t(elapsed.ToMicroseconds()), cmapCount));
|
int32_t(elapsed.ToMicroseconds()), cmapCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
// no match? add to set of non-matching codepoints
|
// no match? add to set of non-matching codepoints
|
||||||
if (!font) {
|
if (!fontEntry) {
|
||||||
mCodepointsWithNoFonts.set(aCh);
|
mCodepointsWithNoFonts.set(aCh);
|
||||||
} else {
|
} else {
|
||||||
*aVisibility = fallbackFamily.mIsShared
|
*aVisibility = fallbackFamily.mIsShared
|
||||||
|
@ -976,19 +957,18 @@ gfxFont* gfxPlatformFontList::SystemFindFontForChar(
|
||||||
Telemetry::Accumulate(Telemetry::SYSTEM_FONT_FALLBACK_SCRIPT,
|
Telemetry::Accumulate(Telemetry::SYSTEM_FONT_FALLBACK_SCRIPT,
|
||||||
int(aRunScript) + 1);
|
int(aRunScript) + 1);
|
||||||
|
|
||||||
return font;
|
return fontEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NUM_FALLBACK_FONTS 8
|
#define NUM_FALLBACK_FONTS 8
|
||||||
|
|
||||||
gfxFont* gfxPlatformFontList::CommonFontFallback(
|
gfxFontEntry* gfxPlatformFontList::CommonFontFallback(
|
||||||
uint32_t aCh, uint32_t aNextCh, Script aRunScript,
|
uint32_t aCh, uint32_t aNextCh, Script aRunScript,
|
||||||
eFontPresentation aPresentation, const gfxFontStyle* aMatchStyle,
|
const gfxFontStyle* aMatchStyle, FontFamily& aMatchedFamily) {
|
||||||
FontFamily& aMatchedFamily) {
|
|
||||||
AutoTArray<const char*, NUM_FALLBACK_FONTS> defaultFallbacks;
|
AutoTArray<const char*, NUM_FALLBACK_FONTS> defaultFallbacks;
|
||||||
gfxPlatform::GetPlatform()->GetCommonFallbackFonts(
|
gfxPlatform::GetPlatform()->GetCommonFallbackFonts(aCh, aNextCh, aRunScript,
|
||||||
aCh, aRunScript, aPresentation, defaultFallbacks);
|
defaultFallbacks);
|
||||||
GlobalFontMatch data(aCh, aNextCh, *aMatchStyle, aPresentation);
|
GlobalFontMatch data(aCh, *aMatchStyle);
|
||||||
if (SharedFontList()) {
|
if (SharedFontList()) {
|
||||||
for (const auto name : defaultFallbacks) {
|
for (const auto name : defaultFallbacks) {
|
||||||
fontlist::Family* family = FindSharedFamily(nsDependentCString(name));
|
fontlist::Family* family = FindSharedFamily(nsDependentCString(name));
|
||||||
|
@ -998,7 +978,7 @@ gfxFont* gfxPlatformFontList::CommonFontFallback(
|
||||||
family->SearchAllFontsForChar(SharedFontList(), &data);
|
family->SearchAllFontsForChar(SharedFontList(), &data);
|
||||||
if (data.mBestMatch) {
|
if (data.mBestMatch) {
|
||||||
aMatchedFamily = FontFamily(family);
|
aMatchedFamily = FontFamily(family);
|
||||||
return data.mBestMatch->FindOrMakeFont(aMatchStyle);
|
return data.mBestMatch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1011,16 +991,15 @@ gfxFont* gfxPlatformFontList::CommonFontFallback(
|
||||||
fallback->FindFontForChar(&data);
|
fallback->FindFontForChar(&data);
|
||||||
if (data.mBestMatch) {
|
if (data.mBestMatch) {
|
||||||
aMatchedFamily = FontFamily(fallback);
|
aMatchedFamily = FontFamily(fallback);
|
||||||
return data.mBestMatch->FindOrMakeFont(aMatchStyle);
|
return data.mBestMatch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxFont* gfxPlatformFontList::GlobalFontFallback(
|
gfxFontEntry* gfxPlatformFontList::GlobalFontFallback(
|
||||||
uint32_t aCh, uint32_t aNextCh, Script aRunScript,
|
const uint32_t aCh, Script aRunScript, const gfxFontStyle* aMatchStyle,
|
||||||
eFontPresentation aPresentation, const gfxFontStyle* aMatchStyle,
|
|
||||||
uint32_t& aCmapCount, FontFamily& aMatchedFamily,
|
uint32_t& aCmapCount, FontFamily& aMatchedFamily,
|
||||||
FontMatchingStats* aFontMatchingStats) {
|
FontMatchingStats* aFontMatchingStats) {
|
||||||
bool useCmaps = IsFontFamilyWhitelistActive() ||
|
bool useCmaps = IsFontFamilyWhitelistActive() ||
|
||||||
|
@ -1033,30 +1012,12 @@ gfxFont* gfxPlatformFontList::GlobalFontFallback(
|
||||||
if (fe) {
|
if (fe) {
|
||||||
if (aMatchedFamily.mIsShared) {
|
if (aMatchedFamily.mIsShared) {
|
||||||
if (IsVisibleToCSS(*aMatchedFamily.mShared)) {
|
if (IsVisibleToCSS(*aMatchedFamily.mShared)) {
|
||||||
gfxFont* font = fe->FindOrMakeFont(aMatchStyle);
|
return fe;
|
||||||
if (font) {
|
|
||||||
if (aPresentation == eFontPresentation::Any) {
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
bool hasColorGlyph = font->HasColorGlyphFor(aCh, aNextCh);
|
|
||||||
if (hasColorGlyph == (aPresentation == eFontPresentation::Emoji)) {
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
rejectedFallbackVisibility = aMatchedFamily.mShared->Visibility();
|
rejectedFallbackVisibility = aMatchedFamily.mShared->Visibility();
|
||||||
} else {
|
} else {
|
||||||
if (IsVisibleToCSS(*aMatchedFamily.mUnshared)) {
|
if (IsVisibleToCSS(*aMatchedFamily.mUnshared)) {
|
||||||
gfxFont* font = fe->FindOrMakeFont(aMatchStyle);
|
return fe;
|
||||||
if (font) {
|
|
||||||
if (aPresentation == eFontPresentation::Any) {
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
bool hasColorGlyph = font->HasColorGlyphFor(aCh, aNextCh);
|
|
||||||
if (hasColorGlyph == (aPresentation == eFontPresentation::Emoji)) {
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
rejectedFallbackVisibility = aMatchedFamily.mUnshared->Visibility();
|
rejectedFallbackVisibility = aMatchedFamily.mUnshared->Visibility();
|
||||||
}
|
}
|
||||||
|
@ -1064,7 +1025,7 @@ gfxFont* gfxPlatformFontList::GlobalFontFallback(
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, try to find it among local fonts
|
// otherwise, try to find it among local fonts
|
||||||
GlobalFontMatch data(aCh, aNextCh, *aMatchStyle, aPresentation);
|
GlobalFontMatch data(aCh, *aMatchStyle);
|
||||||
if (SharedFontList()) {
|
if (SharedFontList()) {
|
||||||
fontlist::Family* families = SharedFontList()->Families();
|
fontlist::Family* families = SharedFontList()->Families();
|
||||||
if (families) {
|
if (families) {
|
||||||
|
@ -1081,7 +1042,7 @@ gfxFont* gfxPlatformFontList::GlobalFontFallback(
|
||||||
}
|
}
|
||||||
if (data.mBestMatch) {
|
if (data.mBestMatch) {
|
||||||
aMatchedFamily = FontFamily(data.mMatchedSharedFamily);
|
aMatchedFamily = FontFamily(data.mMatchedSharedFamily);
|
||||||
return data.mBestMatch->FindOrMakeFont(aMatchStyle);
|
return data.mBestMatch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1103,7 +1064,7 @@ gfxFont* gfxPlatformFontList::GlobalFontFallback(
|
||||||
aCmapCount = data.mCmapsTested;
|
aCmapCount = data.mCmapsTested;
|
||||||
if (data.mBestMatch) {
|
if (data.mBestMatch) {
|
||||||
aMatchedFamily = FontFamily(data.mMatchedFamily);
|
aMatchedFamily = FontFamily(data.mMatchedFamily);
|
||||||
return data.mBestMatch->FindOrMakeFont(aMatchStyle);
|
return data.mBestMatch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -209,12 +209,11 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
|
||||||
|
|
||||||
void GetFontFamilyList(nsTArray<RefPtr<gfxFontFamily>>& aFamilyArray);
|
void GetFontFamilyList(nsTArray<RefPtr<gfxFontFamily>>& aFamilyArray);
|
||||||
|
|
||||||
gfxFont* SystemFindFontForChar(uint32_t aCh, uint32_t aNextCh,
|
gfxFontEntry* SystemFindFontForChar(uint32_t aCh, uint32_t aNextCh,
|
||||||
Script aRunScript,
|
Script aRunScript,
|
||||||
eFontPresentation aPresentation,
|
const gfxFontStyle* aStyle,
|
||||||
const gfxFontStyle* aStyle,
|
FontVisibility* aVisibility,
|
||||||
FontVisibility* aVisibility,
|
FontMatchingStats* aFontMatchingStats);
|
||||||
FontMatchingStats* aFontMatchingStats);
|
|
||||||
|
|
||||||
// Flags to control optional behaviors in FindAndAddFamilies. The sense
|
// Flags to control optional behaviors in FindAndAddFamilies. The sense
|
||||||
// of the bit flags have been chosen such that the default parameter of
|
// of the bit flags have been chosen such that the default parameter of
|
||||||
|
@ -623,17 +622,17 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns default font for a given character, null otherwise
|
// returns default font for a given character, null otherwise
|
||||||
gfxFont* CommonFontFallback(uint32_t aCh, uint32_t aNextCh, Script aRunScript,
|
gfxFontEntry* CommonFontFallback(uint32_t aCh, uint32_t aNextCh,
|
||||||
eFontPresentation aPresentation,
|
Script aRunScript,
|
||||||
const gfxFontStyle* aMatchStyle,
|
const gfxFontStyle* aMatchStyle,
|
||||||
FontFamily& aMatchedFamily);
|
FontFamily& aMatchedFamily);
|
||||||
|
|
||||||
// Search fonts system-wide for a given character, null if not found.
|
// Search fonts system-wide for a given character, null if not found.
|
||||||
gfxFont* GlobalFontFallback(uint32_t aCh, uint32_t aNextCh, Script aRunScript,
|
gfxFontEntry* GlobalFontFallback(const uint32_t aCh, Script aRunScript,
|
||||||
eFontPresentation aPresentation,
|
const gfxFontStyle* aMatchStyle,
|
||||||
const gfxFontStyle* aMatchStyle,
|
uint32_t& aCmapCount,
|
||||||
uint32_t& aCmapCount, FontFamily& aMatchedFamily,
|
FontFamily& aMatchedFamily,
|
||||||
FontMatchingStats* aFontMatchingStats);
|
FontMatchingStats* aFontMatchingStats);
|
||||||
|
|
||||||
// Platform-specific implementation of global font fallback, if any;
|
// Platform-specific implementation of global font fallback, if any;
|
||||||
// this may return nullptr in which case the default cmap-based fallback
|
// this may return nullptr in which case the default cmap-based fallback
|
||||||
|
|
|
@ -206,10 +206,10 @@ static const char kFontWenQuanYiMicroHei[] = "WenQuanYi Micro Hei";
|
||||||
static const char kFontNanumGothic[] = "NanumGothic";
|
static const char kFontNanumGothic[] = "NanumGothic";
|
||||||
static const char kFontSymbola[] = "Symbola";
|
static const char kFontSymbola[] = "Symbola";
|
||||||
|
|
||||||
void gfxPlatformGtk::GetCommonFallbackFonts(uint32_t aCh, Script aRunScript,
|
void gfxPlatformGtk::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
|
||||||
eFontPresentation aPresentation,
|
Script aRunScript,
|
||||||
nsTArray<const char*>& aFontList) {
|
nsTArray<const char*>& aFontList) {
|
||||||
if (aPresentation == eFontPresentation::Emoji) {
|
if (ShouldPreferEmojiFont(aCh, aNextCh)) {
|
||||||
aFontList.AppendElement(kFontTwemojiMozilla);
|
aFontList.AppendElement(kFontTwemojiMozilla);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,8 +42,7 @@ class gfxPlatformGtk final : public gfxPlatform {
|
||||||
|
|
||||||
nsresult UpdateFontList() override;
|
nsresult UpdateFontList() override;
|
||||||
|
|
||||||
void GetCommonFallbackFonts(uint32_t aCh, Script aRunScript,
|
void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, Script aRunScript,
|
||||||
eFontPresentation aPresentation,
|
|
||||||
nsTArray<const char*>& aFontList) override;
|
nsTArray<const char*>& aFontList) override;
|
||||||
|
|
||||||
gfxPlatformFontList* CreatePlatformFontList() override;
|
gfxPlatformFontList* CreatePlatformFontList() override;
|
||||||
|
|
|
@ -171,10 +171,10 @@ static const char kFontSTIXGeneral[] = "STIXGeneral";
|
||||||
static const char kFontTamilMN[] = "Tamil MN";
|
static const char kFontTamilMN[] = "Tamil MN";
|
||||||
static const char kFontZapfDingbats[] = "Zapf Dingbats";
|
static const char kFontZapfDingbats[] = "Zapf Dingbats";
|
||||||
|
|
||||||
void gfxPlatformMac::GetCommonFallbackFonts(uint32_t aCh, Script aRunScript,
|
void gfxPlatformMac::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
|
||||||
eFontPresentation aPresentation,
|
Script aRunScript,
|
||||||
nsTArray<const char*>& aFontList) {
|
nsTArray<const char*>& aFontList) {
|
||||||
if (aPresentation == eFontPresentation::Emoji) {
|
if (ShouldPreferEmojiFont(aCh, aNextCh)) {
|
||||||
aFontList.AppendElement(kFontAppleColorEmoji);
|
aFontList.AppendElement(kFontAppleColorEmoji);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,7 @@ class gfxPlatformMac : public gfxPlatform {
|
||||||
|
|
||||||
bool IsFontFormatSupported(uint32_t aFormatFlags) override;
|
bool IsFontFormatSupported(uint32_t aFormatFlags) override;
|
||||||
|
|
||||||
void GetCommonFallbackFonts(uint32_t aCh, Script aRunScript,
|
void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, Script aRunScript,
|
||||||
eFontPresentation aPresentation,
|
|
||||||
nsTArray<const char*>& aFontList) override;
|
nsTArray<const char*>& aFontList) override;
|
||||||
|
|
||||||
// lookup the system font for a particular system font type and set
|
// lookup the system font for a particular system font type and set
|
||||||
|
|
|
@ -2909,10 +2909,9 @@ gfxTextRun* gfxFontGroup::GetEllipsisTextRun(
|
||||||
return mCachedEllipsisTextRun.get();
|
return mCachedEllipsisTextRun.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxFont* gfxFontGroup::FindFallbackFaceForChar(
|
gfxFont* gfxFontGroup::FindFallbackFaceForChar(gfxFontFamily* aFamily,
|
||||||
gfxFontFamily* aFamily, uint32_t aCh, uint32_t aNextCh,
|
uint32_t aCh) {
|
||||||
eFontPresentation aPresentation) {
|
GlobalFontMatch data(aCh, mStyle);
|
||||||
GlobalFontMatch data(aCh, aNextCh, mStyle, aPresentation);
|
|
||||||
aFamily->SearchAllFontsForChar(&data);
|
aFamily->SearchAllFontsForChar(&data);
|
||||||
gfxFontEntry* fe = data.mBestMatch;
|
gfxFontEntry* fe = data.mBestMatch;
|
||||||
if (!fe) {
|
if (!fe) {
|
||||||
|
@ -2921,12 +2920,11 @@ gfxFont* gfxFontGroup::FindFallbackFaceForChar(
|
||||||
return fe->FindOrMakeFont(&mStyle);
|
return fe->FindOrMakeFont(&mStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxFont* gfxFontGroup::FindFallbackFaceForChar(
|
gfxFont* gfxFontGroup::FindFallbackFaceForChar(fontlist::Family* aFamily,
|
||||||
fontlist::Family* aFamily, uint32_t aCh, uint32_t aNextCh,
|
uint32_t aCh) {
|
||||||
eFontPresentation aPresentation) {
|
|
||||||
fontlist::FontList* list =
|
fontlist::FontList* list =
|
||||||
gfxPlatformFontList::PlatformFontList()->SharedFontList();
|
gfxPlatformFontList::PlatformFontList()->SharedFontList();
|
||||||
GlobalFontMatch data(aCh, aNextCh, mStyle, aPresentation);
|
GlobalFontMatch data(aCh, mStyle);
|
||||||
aFamily->SearchAllFontsForChar(list, &data);
|
aFamily->SearchAllFontsForChar(list, &data);
|
||||||
gfxFontEntry* fe = data.mBestMatch;
|
gfxFontEntry* fe = data.mBestMatch;
|
||||||
if (!fe) {
|
if (!fe) {
|
||||||
|
@ -2935,15 +2933,12 @@ gfxFont* gfxFontGroup::FindFallbackFaceForChar(
|
||||||
return fe->FindOrMakeFont(&mStyle);
|
return fe->FindOrMakeFont(&mStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxFont* gfxFontGroup::FindFallbackFaceForChar(
|
gfxFont* gfxFontGroup::FindFallbackFaceForChar(const FamilyFace& aFamily,
|
||||||
const FamilyFace& aFamily, uint32_t aCh, uint32_t aNextCh,
|
uint32_t aCh) {
|
||||||
eFontPresentation aPresentation) {
|
|
||||||
if (aFamily.IsSharedFamily()) {
|
if (aFamily.IsSharedFamily()) {
|
||||||
return FindFallbackFaceForChar(aFamily.SharedFamily(), aCh, aNextCh,
|
return FindFallbackFaceForChar(aFamily.SharedFamily(), aCh);
|
||||||
aPresentation);
|
|
||||||
}
|
}
|
||||||
return FindFallbackFaceForChar(aFamily.OwnedFamily(), aCh, aNextCh,
|
return FindFallbackFaceForChar(aFamily.OwnedFamily(), aCh);
|
||||||
aPresentation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxFloat gfxFontGroup::GetUnderlineOffset() {
|
gfxFloat gfxFontGroup::GetUnderlineOffset() {
|
||||||
|
@ -3035,41 +3030,12 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
|
||||||
bool isJoinControl = gfxFontUtils::IsJoinControl(aCh);
|
bool isJoinControl = gfxFontUtils::IsJoinControl(aCh);
|
||||||
bool wasJoinCauser = gfxFontUtils::IsJoinCauser(aPrevCh);
|
bool wasJoinCauser = gfxFontUtils::IsJoinCauser(aPrevCh);
|
||||||
bool isVarSelector = gfxFontUtils::IsVarSelector(aCh);
|
bool isVarSelector = gfxFontUtils::IsVarSelector(aCh);
|
||||||
bool nextIsVarSelector = gfxFontUtils::IsVarSelector(aNextCh);
|
|
||||||
|
|
||||||
// Whether we've seen a font that is currently loading a resource that may
|
// Whether we've seen a font that is currently loading a resource that may
|
||||||
// provide this character (so we should not start a new load).
|
// provide this character (so we should not start a new load).
|
||||||
bool loading = false;
|
bool loading = false;
|
||||||
|
|
||||||
// Do we need to explicitly look for a font that does or does not provide a
|
if (!isJoinControl && !wasJoinCauser && !isVarSelector) {
|
||||||
// color glyph for the given character?
|
|
||||||
// For characters with no `EMOJI` property, we'll use whatever the family
|
|
||||||
// list calls for; but if it's a potential emoji codepoint, we need to check
|
|
||||||
// if there's a variation selector specifically asking for Text-style or
|
|
||||||
// Emoji-style rendering and look for a suitable font.
|
|
||||||
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.
|
|
||||||
if (aNextCh == kVariationSelector16 ||
|
|
||||||
(emojiPresentation == EmojiPresentation::EmojiDefault &&
|
|
||||||
aNextCh != kVariationSelector15) ||
|
|
||||||
(aNextCh >= kEmojiSkinToneFirst && aNextCh <= kEmojiSkinToneLast)) {
|
|
||||||
presentation = eFontPresentation::Emoji;
|
|
||||||
} else if (aNextCh == kVariationSelector15) {
|
|
||||||
presentation = eFontPresentation::Text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isJoinControl && !wasJoinCauser && !isVarSelector &&
|
|
||||||
!nextIsVarSelector && presentation == eFontPresentation::Any) {
|
|
||||||
gfxFont* firstFont = GetFontAt(0, aCh, &loading);
|
gfxFont* firstFont = GetFontAt(0, aCh, &loading);
|
||||||
if (firstFont) {
|
if (firstFont) {
|
||||||
if (firstFont->HasCharacter(aCh)) {
|
if (firstFont->HasCharacter(aCh)) {
|
||||||
|
@ -3079,13 +3045,13 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
|
||||||
|
|
||||||
gfxFont* font = nullptr;
|
gfxFont* font = nullptr;
|
||||||
if (mFonts[0].CheckForFallbackFaces()) {
|
if (mFonts[0].CheckForFallbackFaces()) {
|
||||||
font = FindFallbackFaceForChar(mFonts[0], aCh, aNextCh, presentation);
|
font = FindFallbackFaceForChar(mFonts[0], aCh);
|
||||||
} else if (!firstFont->GetFontEntry()->IsUserFont()) {
|
} else if (!firstFont->GetFontEntry()->IsUserFont()) {
|
||||||
// For platform fonts (but not userfonts), we may need to do
|
// For platform fonts (but not userfonts), we may need to do
|
||||||
// fallback within the family to handle cases where some faces
|
// fallback within the family to handle cases where some faces
|
||||||
// such as Italic or Black have reduced character sets compared
|
// such as Italic or Black have reduced character sets compared
|
||||||
// to the family's Regular face.
|
// to the family's Regular face.
|
||||||
font = FindFallbackFaceForChar(mFonts[0], aCh, aNextCh, presentation);
|
font = FindFallbackFaceForChar(mFonts[0], aCh);
|
||||||
}
|
}
|
||||||
if (font) {
|
if (font) {
|
||||||
*aMatchType = {FontMatchType::Kind::kFontGroup, mFonts[0].Generic()};
|
*aMatchType = {FontMatchType::Kind::kFontGroup, mFonts[0].Generic()};
|
||||||
|
@ -3127,36 +3093,6 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
|
||||||
return aPrevMatchedFont;
|
return aPrevMatchedFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to remember the first "candidate" font that would provide a fallback
|
|
||||||
// text-style rendering if no color glyph can be found.
|
|
||||||
gfxFont* candidateFont = nullptr;
|
|
||||||
FontMatchType candidateMatchType;
|
|
||||||
|
|
||||||
// Handle a candidate font that could support the character, returning true
|
|
||||||
// if we should go ahead and return |f|, false to continue searching.
|
|
||||||
auto CheckCandidate = [&](gfxFont* f, FontMatchType t) -> bool {
|
|
||||||
// If no preference, then just accept the font.
|
|
||||||
if (presentation == eFontPresentation::Any) {
|
|
||||||
RefPtr<gfxFont> autoRefDeref(candidateFont);
|
|
||||||
*aMatchType = t;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Does the candidate font provide a color glyph for the current character?
|
|
||||||
bool hasColorGlyph = f->HasColorGlyphFor(aCh, aNextCh);
|
|
||||||
// If the provided glyph matches the preference, accept the font.
|
|
||||||
if (hasColorGlyph == (presentation == eFontPresentation::Emoji)) {
|
|
||||||
RefPtr<gfxFont> autoRefDeref(candidateFont);
|
|
||||||
*aMatchType = t;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Otherwise, remember the first potential fallback, but keep searching.
|
|
||||||
if (!candidateFont) {
|
|
||||||
candidateFont = f;
|
|
||||||
candidateMatchType = t;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 1. check remaining fonts in the font group
|
// 1. check remaining fonts in the font group
|
||||||
for (uint32_t i = nextIndex; i < fontListLength; i++) {
|
for (uint32_t i = nextIndex; i < fontListLength; i++) {
|
||||||
FamilyFace& ff = mFonts[i];
|
FamilyFace& ff = mFonts[i];
|
||||||
|
@ -3171,10 +3107,8 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
|
||||||
if (font) {
|
if (font) {
|
||||||
// if available, use already-made gfxFont and check for character
|
// if available, use already-made gfxFont and check for character
|
||||||
if (font->HasCharacter(aCh)) {
|
if (font->HasCharacter(aCh)) {
|
||||||
if (CheckCandidate(font,
|
*aMatchType = {FontMatchType::Kind::kFontGroup, ff.Generic()};
|
||||||
{FontMatchType::Kind::kFontGroup, ff.Generic()})) {
|
return font;
|
||||||
return font;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// don't have a gfxFont yet, test charmap before instantiating
|
// don't have a gfxFont yet, test charmap before instantiating
|
||||||
|
@ -3205,10 +3139,9 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
|
||||||
if (pfe && pfe->HasCharacter(aCh)) {
|
if (pfe && pfe->HasCharacter(aCh)) {
|
||||||
font = GetFontAt(i, aCh, &loading);
|
font = GetFontAt(i, aCh, &loading);
|
||||||
if (font) {
|
if (font) {
|
||||||
if (CheckCandidate(font, {FontMatchType::Kind::kFontGroup,
|
*aMatchType = {FontMatchType::Kind::kFontGroup,
|
||||||
mFonts[i].Generic()})) {
|
mFonts[i].Generic()};
|
||||||
return font;
|
return font;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (fe && fe->HasCharacter(aCh)) {
|
} else if (fe && fe->HasCharacter(aCh)) {
|
||||||
|
@ -3216,10 +3149,8 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
|
||||||
// build the font via GetFontAt
|
// build the font via GetFontAt
|
||||||
font = GetFontAt(i, aCh, &loading);
|
font = GetFontAt(i, aCh, &loading);
|
||||||
if (font) {
|
if (font) {
|
||||||
if (CheckCandidate(font, {FontMatchType::Kind::kFontGroup,
|
*aMatchType = {FontMatchType::Kind::kFontGroup, mFonts[i].Generic()};
|
||||||
mFonts[i].Generic()})) {
|
return font;
|
||||||
return font;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3240,12 +3171,10 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
|
||||||
"should only do fallback once per font family");
|
"should only do fallback once per font family");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
font = FindFallbackFaceForChar(ff, aCh, aNextCh, presentation);
|
font = FindFallbackFaceForChar(ff, aCh);
|
||||||
if (font) {
|
if (font) {
|
||||||
if (CheckCandidate(font,
|
*aMatchType = {FontMatchType::Kind::kFontGroup, ff.Generic()};
|
||||||
{FontMatchType::Kind::kFontGroup, ff.Generic()})) {
|
return font;
|
||||||
return font;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// For platform fonts, but not user fonts, consider intra-family
|
// For platform fonts, but not user fonts, consider intra-family
|
||||||
|
@ -3253,12 +3182,10 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
|
||||||
// also above).
|
// also above).
|
||||||
gfxFontEntry* fe = ff.FontEntry();
|
gfxFontEntry* fe = ff.FontEntry();
|
||||||
if (fe && !fe->mIsUserFontContainer && !fe->IsUserFont()) {
|
if (fe && !fe->mIsUserFontContainer && !fe->IsUserFont()) {
|
||||||
font = FindFallbackFaceForChar(ff, aCh, aNextCh, presentation);
|
font = FindFallbackFaceForChar(ff, aCh);
|
||||||
if (font) {
|
if (font) {
|
||||||
if (CheckCandidate(font,
|
*aMatchType = {FontMatchType::Kind::kFontGroup, ff.Generic()};
|
||||||
{FontMatchType::Kind::kFontGroup, ff.Generic()})) {
|
return font;
|
||||||
return font;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3267,9 +3194,8 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
|
||||||
if (fontListLength == 0) {
|
if (fontListLength == 0) {
|
||||||
gfxFont* defaultFont = GetDefaultFont();
|
gfxFont* defaultFont = GetDefaultFont();
|
||||||
if (defaultFont->HasCharacter(aCh)) {
|
if (defaultFont->HasCharacter(aCh)) {
|
||||||
if (CheckCandidate(defaultFont, FontMatchType::Kind::kFontGroup)) {
|
*aMatchType = FontMatchType::Kind::kFontGroup;
|
||||||
return defaultFont;
|
return defaultFont;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3282,56 +3208,34 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
|
||||||
// fallback has already noted a failure.
|
// fallback has already noted a failure.
|
||||||
if (gfxPlatformFontList::PlatformFontList()->SkipFontFallbackForChar(aCh) ||
|
if (gfxPlatformFontList::PlatformFontList()->SkipFontFallbackForChar(aCh) ||
|
||||||
GetGeneralCategory(aCh) == HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED) {
|
GetGeneralCategory(aCh) == HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED) {
|
||||||
if (candidateFont) {
|
return nullptr;
|
||||||
*aMatchType = candidateMatchType;
|
|
||||||
}
|
|
||||||
return candidateFont;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. search pref fonts
|
// 2. search pref fonts
|
||||||
gfxFont* font = WhichPrefFontSupportsChar(aCh, aNextCh, presentation);
|
gfxFont* font = WhichPrefFontSupportsChar(aCh, aNextCh);
|
||||||
if (font) {
|
if (font) {
|
||||||
if (CheckCandidate(font, FontMatchType::Kind::kPrefsFallback)) {
|
*aMatchType = FontMatchType::Kind::kPrefsFallback;
|
||||||
return font;
|
return font;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For fallback searches, we don't want to use a color-emoji font unless
|
|
||||||
// emoji-style presentation is specifically required, so we map Any to
|
|
||||||
// Text here.
|
|
||||||
if (presentation == eFontPresentation::Any) {
|
|
||||||
presentation = eFontPresentation::Text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. use fallback fonts
|
// 3. use fallback fonts
|
||||||
// -- before searching for something else check the font used for the
|
// -- before searching for something else check the font used for the
|
||||||
// previous character
|
// previous character
|
||||||
if (aPrevMatchedFont && aPrevMatchedFont->HasCharacter(aCh)) {
|
if (aPrevMatchedFont && aPrevMatchedFont->HasCharacter(aCh)) {
|
||||||
if (CheckCandidate(aPrevMatchedFont,
|
*aMatchType = FontMatchType::Kind::kSystemFallback;
|
||||||
FontMatchType::Kind::kSystemFallback)) {
|
return aPrevMatchedFont;
|
||||||
return aPrevMatchedFont;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// for known "space" characters, don't do a full system-fallback search;
|
// for known "space" characters, don't do a full system-fallback search;
|
||||||
// we'll synthesize appropriate-width spaces instead of missing-glyph boxes
|
// we'll synthesize appropriate-width spaces instead of missing-glyph boxes
|
||||||
if (GetGeneralCategory(aCh) == HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR &&
|
if (GetGeneralCategory(aCh) == HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR &&
|
||||||
GetFirstValidFont()->SynthesizeSpaceWidth(aCh) >= 0.0) {
|
GetFirstValidFont()->SynthesizeSpaceWidth(aCh) >= 0.0) {
|
||||||
RefPtr<gfxFont> autoRefDeref(candidateFont);
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- otherwise look for other stuff
|
// -- otherwise look for other stuff
|
||||||
font = WhichSystemFontSupportsChar(aCh, aNextCh, aRunScript, presentation);
|
*aMatchType = FontMatchType::Kind::kSystemFallback;
|
||||||
if (font) {
|
return WhichSystemFontSupportsChar(aCh, aNextCh, aRunScript);
|
||||||
if (CheckCandidate(font, FontMatchType::Kind::kSystemFallback)) {
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (candidateFont) {
|
|
||||||
*aMatchType = candidateMatchType;
|
|
||||||
}
|
|
||||||
return candidateFont;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -3403,8 +3307,7 @@ void gfxFontGroup::ComputeRanges(nsTArray<TextRange>& aRanges, const T* aString,
|
||||||
(!IsClusterExtender(ch) && ch != NARROW_NO_BREAK_SPACE &&
|
(!IsClusterExtender(ch) && ch != NARROW_NO_BREAK_SPACE &&
|
||||||
!gfxFontUtils::IsJoinControl(ch) &&
|
!gfxFontUtils::IsJoinControl(ch) &&
|
||||||
!gfxFontUtils::IsJoinCauser(prevCh) &&
|
!gfxFontUtils::IsJoinCauser(prevCh) &&
|
||||||
!gfxFontUtils::IsVarSelector(ch) &&
|
!gfxFontUtils::IsVarSelector(ch)))) {
|
||||||
GetEmojiPresentation(ch) == TextOnly))) {
|
|
||||||
matchType = {FontMatchType::Kind::kFontGroup, mFonts[0].Generic()};
|
matchType = {FontMatchType::Kind::kFontGroup, mFonts[0].Generic()};
|
||||||
} else {
|
} else {
|
||||||
font =
|
font =
|
||||||
|
@ -3590,12 +3493,12 @@ bool gfxFontGroup::ContainsUserFont(const gfxUserFontEntry* aUserFont) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxFont* gfxFontGroup::WhichPrefFontSupportsChar(
|
gfxFont* gfxFontGroup::WhichPrefFontSupportsChar(uint32_t aCh,
|
||||||
uint32_t aCh, uint32_t aNextCh, eFontPresentation aPresentation) {
|
uint32_t aNextCh) {
|
||||||
eFontPrefLang charLang;
|
eFontPrefLang charLang;
|
||||||
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
|
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
|
||||||
|
|
||||||
if (aPresentation == eFontPresentation::Emoji) {
|
if (ShouldPreferEmojiFont(aCh, aNextCh)) {
|
||||||
charLang = eFontPrefLang_Emoji;
|
charLang = eFontPrefLang_Emoji;
|
||||||
} else {
|
} else {
|
||||||
// get the pref font list if it hasn't been set up already
|
// get the pref font list if it hasn't been set up already
|
||||||
|
@ -3671,10 +3574,8 @@ gfxFont* gfxFontGroup::WhichPrefFontSupportsChar(
|
||||||
// alternative face in the same family.
|
// alternative face in the same family.
|
||||||
if (!prefFont) {
|
if (!prefFont) {
|
||||||
prefFont = family.mIsShared
|
prefFont = family.mIsShared
|
||||||
? FindFallbackFaceForChar(family.mShared, aCh, aNextCh,
|
? FindFallbackFaceForChar(family.mShared, aCh)
|
||||||
aPresentation)
|
: FindFallbackFaceForChar(family.mUnshared, aCh);
|
||||||
: FindFallbackFaceForChar(family.mUnshared, aCh, aNextCh,
|
|
||||||
aPresentation);
|
|
||||||
}
|
}
|
||||||
if (prefFont) {
|
if (prefFont) {
|
||||||
mLastPrefFamily = family;
|
mLastPrefFamily = family;
|
||||||
|
@ -3692,15 +3593,14 @@ gfxFont* gfxFontGroup::WhichPrefFontSupportsChar(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxFont* gfxFontGroup::WhichSystemFontSupportsChar(
|
gfxFont* gfxFontGroup::WhichSystemFontSupportsChar(uint32_t aCh,
|
||||||
uint32_t aCh, uint32_t aNextCh, Script aRunScript,
|
uint32_t aNextCh,
|
||||||
eFontPresentation aPresentation) {
|
Script aRunScript) {
|
||||||
FontVisibility visibility;
|
FontVisibility visibility;
|
||||||
gfxFont* font =
|
gfxFontEntry* fe =
|
||||||
gfxPlatformFontList::PlatformFontList()->SystemFindFontForChar(
|
gfxPlatformFontList::PlatformFontList()->SystemFindFontForChar(
|
||||||
aCh, aNextCh, aRunScript, aPresentation, &mStyle, &visibility,
|
aCh, aNextCh, aRunScript, &mStyle, &visibility, mFontMatchingStats);
|
||||||
mFontMatchingStats);
|
if (fe) {
|
||||||
if (font) {
|
|
||||||
if (mFontMatchingStats) {
|
if (mFontMatchingStats) {
|
||||||
switch (visibility) {
|
switch (visibility) {
|
||||||
case FontVisibility::Unknown:
|
case FontVisibility::Unknown:
|
||||||
|
@ -3728,7 +3628,7 @@ gfxFont* gfxFontGroup::WhichSystemFontSupportsChar(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return font;
|
return fe->FindOrMakeFont(&mStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -1113,12 +1113,10 @@ class gfxFontGroup final : public gfxTextRunFactory {
|
||||||
|
|
||||||
// search through pref fonts for a character, return nullptr if no matching
|
// search through pref fonts for a character, return nullptr if no matching
|
||||||
// pref font
|
// pref font
|
||||||
gfxFont* WhichPrefFontSupportsChar(uint32_t aCh, uint32_t aNextCh,
|
gfxFont* WhichPrefFontSupportsChar(uint32_t aCh, uint32_t aNextCh);
|
||||||
eFontPresentation aPresentation);
|
|
||||||
|
|
||||||
gfxFont* WhichSystemFontSupportsChar(uint32_t aCh, uint32_t aNextCh,
|
gfxFont* WhichSystemFontSupportsChar(uint32_t aCh, uint32_t aNextCh,
|
||||||
Script aRunScript,
|
Script aRunScript);
|
||||||
eFontPresentation aPresentation);
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void ComputeRanges(nsTArray<TextRange>& aRanges, const T* aString,
|
void ComputeRanges(nsTArray<TextRange>& aRanges, const T* aString,
|
||||||
|
@ -1470,17 +1468,12 @@ class gfxFontGroup final : public gfxTextRunFactory {
|
||||||
// Helper for font-matching:
|
// Helper for font-matching:
|
||||||
// search all faces in a family for a fallback in cases where it's unclear
|
// search all faces in a family for a fallback in cases where it's unclear
|
||||||
// whether the family might have a font for a given character
|
// whether the family might have a font for a given character
|
||||||
gfxFont* FindFallbackFaceForChar(const FamilyFace& aFamily, uint32_t aCh,
|
gfxFont* FindFallbackFaceForChar(const FamilyFace& aFamily, uint32_t aCh);
|
||||||
uint32_t aNextCh,
|
|
||||||
eFontPresentation aPresentation);
|
|
||||||
|
|
||||||
gfxFont* FindFallbackFaceForChar(mozilla::fontlist::Family* aFamily,
|
gfxFont* FindFallbackFaceForChar(mozilla::fontlist::Family* aFamily,
|
||||||
uint32_t aCh, uint32_t aNextCh,
|
uint32_t aCh);
|
||||||
eFontPresentation aPresentation);
|
|
||||||
|
|
||||||
gfxFont* FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh,
|
gfxFont* FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh);
|
||||||
uint32_t aNextCh,
|
|
||||||
eFontPresentation aPresentation);
|
|
||||||
|
|
||||||
// helper methods for looking up fonts
|
// helper methods for looking up fonts
|
||||||
|
|
||||||
|
|
|
@ -663,9 +663,9 @@ static const char kFontUtsaah[] = "Utsaah";
|
||||||
static const char kFontYuGothic[] = "Yu Gothic";
|
static const char kFontYuGothic[] = "Yu Gothic";
|
||||||
|
|
||||||
void gfxWindowsPlatform::GetCommonFallbackFonts(
|
void gfxWindowsPlatform::GetCommonFallbackFonts(
|
||||||
uint32_t aCh, Script aRunScript, eFontPresentation aPresentation,
|
uint32_t aCh, uint32_t aNextCh, Script aRunScript,
|
||||||
nsTArray<const char*>& aFontList) {
|
nsTArray<const char*>& aFontList) {
|
||||||
if (aPresentation == eFontPresentation::Emoji) {
|
if (ShouldPreferEmojiFont(aCh, aNextCh)) {
|
||||||
aFontList.AppendElement(kFontSegoeUIEmoji);
|
aFontList.AppendElement(kFontSegoeUIEmoji);
|
||||||
aFontList.AppendElement(kFontTwemojiMozilla);
|
aFontList.AppendElement(kFontTwemojiMozilla);
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,8 +148,7 @@ class gfxWindowsPlatform final : public gfxPlatform {
|
||||||
*/
|
*/
|
||||||
void VerifyD2DDevice(bool aAttemptForce);
|
void VerifyD2DDevice(bool aAttemptForce);
|
||||||
|
|
||||||
void GetCommonFallbackFonts(uint32_t aCh, Script aRunScript,
|
void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, Script aRunScript,
|
||||||
eFontPresentation aPresentation,
|
|
||||||
nsTArray<const char*>& aFontList) override;
|
nsTArray<const char*>& aFontList) override;
|
||||||
|
|
||||||
bool CanUseHardwareVideoDecoding() override;
|
bool CanUseHardwareVideoDecoding() override;
|
||||||
|
|
|
@ -182,6 +182,19 @@ inline EmojiPresentation GetEmojiPresentation(uint32_t aCh) {
|
||||||
return TextDefault;
|
return TextDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool ShouldPreferEmojiFont(uint32_t aCh, uint32_t aNextCh) {
|
||||||
|
EmojiPresentation emoji = GetEmojiPresentation(aCh);
|
||||||
|
if (emoji != EmojiPresentation::TextOnly) {
|
||||||
|
if (aNextCh == kVariationSelector16 ||
|
||||||
|
(aNextCh != kVariationSelector15 &&
|
||||||
|
emoji == EmojiPresentation::EmojiDefault) ||
|
||||||
|
(aNextCh >= kEmojiSkinToneFirst && aNextCh <= kEmojiSkinToneLast)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// returns the simplified Gen Category as defined in nsUGenCategory
|
// returns the simplified Gen Category as defined in nsUGenCategory
|
||||||
inline nsUGenCategory GetGenCategory(uint32_t aCh) {
|
inline nsUGenCategory GetGenCategory(uint32_t aCh) {
|
||||||
return sDetailedToGeneralCategory[GetGeneralCategory(aCh)];
|
return sDetailedToGeneralCategory[GetGeneralCategory(aCh)];
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id=test>⌚︎⌛︎🌀︎🌁︎</div>
|
<div id=test>⌚⌛🌀🌁</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -5,10 +5,6 @@
|
||||||
<title>emoji fallback to text font</title>
|
<title>emoji fallback to text font</title>
|
||||||
<style>
|
<style>
|
||||||
#test {
|
#test {
|
||||||
/* Because of the presence of the U+FE0E variation selectors, we should prefer the
|
|
||||||
the monochrome fonts even though color-emoji fonts are listed first. */
|
|
||||||
font-family: 'Segoe UI Emoji', 'Twemoji Mozilla', 'Apple Color Emoji', 'Noto Color Emoji',
|
|
||||||
'Segoe UI Symbol', 'Apple Symbols', 'Noto Sans Symbols';
|
|
||||||
font-size: 24pt;
|
font-size: 24pt;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<title>emoji fallback to color font</title>
|
<title>emoji fallback to color font</title>
|
||||||
<style>
|
<style>
|
||||||
#test {
|
#test {
|
||||||
font-family: 'Segoe UI Emoji', 'Twemoji Mozilla', 'Apple Color Emoji', 'Noto Color Emoji';
|
font-family: 'Segoe UI Emoji', 'Apple Color Emoji', 'Twemoji Mozilla', 'Noto Color Emoji';
|
||||||
font-size: 24pt;
|
font-size: 24pt;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -5,10 +5,6 @@
|
||||||
<title>emoji fallback to color font</title>
|
<title>emoji fallback to color font</title>
|
||||||
<style>
|
<style>
|
||||||
#test {
|
#test {
|
||||||
/* Because of the presence of the U+FE0F variation selectors, we should find
|
|
||||||
a color-emoji font even though the b/w symbol fonts are listed first. */
|
|
||||||
font-family: 'Segoe UI Symbol', 'Apple Symbols', 'Noto Sans Symbols',
|
|
||||||
'Segoe UI Emoji', 'Twemoji Mozilla', 'Apple Color Emoji', 'Noto Color Emoji';
|
|
||||||
font-size: 24pt;
|
font-size: 24pt;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -19,4 +19,4 @@ span {
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
P<span> (fail) </span>A<span>ሴ顶ꯍ</span>S<span>𐐀🌳︎</span>S
|
P<span> (fail) </span>A<span>ሴ顶ꯍ</span>S<span>𐐀🌳</span>S
|
||||||
|
|
|
@ -187,7 +187,7 @@ random-if(!winWidget) == arial-bold-lam-alef-1.html arial-bold-lam-alef-1-ref.ht
|
||||||
fails-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1320665-cmap-format-13.html 1320665-cmap-format-13-ref.html # see bug 1320665 comments 8-9
|
fails-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1320665-cmap-format-13.html 1320665-cmap-format-13-ref.html # see bug 1320665 comments 8-9
|
||||||
== 1331339-script-extensions-shaping-1.html 1331339-script-extensions-shaping-1-ref.html
|
== 1331339-script-extensions-shaping-1.html 1331339-script-extensions-shaping-1-ref.html
|
||||||
skip-if(!cocoaWidget) != 1349308-1.html 1349308-notref.html # macOS-specific test for -apple-system glyph metrics
|
skip-if(!cocoaWidget) != 1349308-1.html 1349308-notref.html # macOS-specific test for -apple-system glyph metrics
|
||||||
fuzzy-if(Android,0-128,0-233) == 1463020-letter-spacing-text-transform-1.html 1463020-letter-spacing-text-transform-1-ref.html
|
fuzzy-if(Android,0-128,0-233) fails-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) == 1463020-letter-spacing-text-transform-1.html 1463020-letter-spacing-text-transform-1-ref.html # Win10: regional indicators not supported by system emoji font
|
||||||
fails-if(Android) == 1463020-letter-spacing-text-transform-2.html 1463020-letter-spacing-text-transform-2-ref.html # missing font coverage on Android
|
fails-if(Android) == 1463020-letter-spacing-text-transform-2.html 1463020-letter-spacing-text-transform-2-ref.html # missing font coverage on Android
|
||||||
== 1507661-spurious-hyphenation-after-explicit.html 1507661-spurious-hyphenation-after-explicit-ref.html
|
== 1507661-spurious-hyphenation-after-explicit.html 1507661-spurious-hyphenation-after-explicit-ref.html
|
||||||
fuzzy-if(!webrender,12-66,288-1681) fails-if(gtkWidget&&!webrender) == 1522857-1.html 1522857-1-ref.html # antialiasing fuzz in non-webrender cases
|
fuzzy-if(!webrender,12-66,288-1681) fails-if(gtkWidget&&!webrender) == 1522857-1.html 1522857-1-ref.html # antialiasing fuzz in non-webrender cases
|
||||||
|
|
|
@ -21,9 +21,7 @@
|
||||||
<script>
|
<script>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
function text(n) {
|
function text(n) {
|
||||||
// Include U+FE0E variation selector to ensure font selection doesn't
|
return "\u{1F310}".repeat(n);
|
||||||
// seek out a color-emoji font in preference to Fira.
|
|
||||||
return "\u{1F310}\u{FE0E}".repeat(n);
|
|
||||||
}
|
}
|
||||||
var e = "\u{2026}";
|
var e = "\u{2026}";
|
||||||
document.getElementById("start").value = e + text(4);
|
document.getElementById("start").value = e + text(4);
|
||||||
|
|
|
@ -21,9 +21,7 @@
|
||||||
<script>
|
<script>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
function text(n) {
|
function text(n) {
|
||||||
// Include U+FE0E variation selector to ensure font selection doesn't
|
return "\u{1F310}".repeat(n);
|
||||||
// seek out a color-emoji font in preference to Fira.
|
|
||||||
return "\u{1F310}\u{FE0E}".repeat(n);
|
|
||||||
}
|
}
|
||||||
document.getElementById("start").value = text(10);
|
document.getElementById("start").value = text(10);
|
||||||
document.getElementById("end").value = text(10);
|
document.getElementById("end").value = text(10);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче