Bug 727276 - Use emoji-style variation selector to help GetCommonFallbackFonts make an appropriate choice. r=roc

This commit is contained in:
Jonathan Kew 2014-09-30 07:27:55 +01:00
parent 5404757967
commit 21d25f9507
14 changed files with 81 additions and 36 deletions

View File

@ -173,13 +173,18 @@ IsJapaneseLocale()
}
void
gfxAndroidPlatform::GetCommonFallbackFonts(const uint32_t aCh,
gfxAndroidPlatform::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
int32_t aRunScript,
nsTArray<const char*>& aFontList)
{
static const char kDroidSansJapanese[] = "Droid Sans Japanese";
static const char kMotoyaLMaru[] = "MotoyaLMaru";
if (aNextCh == 0xfe0fu) {
// if char is followed by VS16, try for a color emoji glyph
aFontList.AppendElement("Noto Color Emoji");
}
if (IS_IN_BMP(aCh)) {
// try language-specific "Droid Sans *" and "Noto Sans *" fonts for
// certain blocks, as most devices probably have these

View File

@ -58,7 +58,7 @@ public:
const uint8_t* aFontData,
uint32_t aLength);
virtual void GetCommonFallbackFonts(const uint32_t aCh,
virtual void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
int32_t aRunScript,
nsTArray<const char*>& aFontList);

View File

@ -1410,7 +1410,7 @@ gfxPangoFontGroup::GetFontSet(PangoLanguage *aLang)
already_AddRefed<gfxFont>
gfxPangoFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
int32_t aRunScript,
uint32_t aNextCh, int32_t aRunScript,
gfxFont *aPrevMatchedFont,
uint8_t *aMatchType)
{

View File

@ -37,8 +37,8 @@ public:
virtual void UpdateUserFonts();
virtual already_AddRefed<gfxFont>
FindFontForChar(uint32_t aCh, uint32_t aPrevCh, int32_t aRunScript,
gfxFont *aPrevMatchedFont,
FindFontForChar(uint32_t aCh, uint32_t aPrevCh, uint32_t aNextCh,
int32_t aRunScript, gfxFont *aPrevMatchedFont,
uint8_t *aMatchType);
static void Shutdown();

View File

@ -449,7 +449,7 @@ public:
// returns a list of commonly used fonts for a given character
// these are *possible* matches, no cmap-checking is done at this level
virtual void GetCommonFallbackFonts(const uint32_t /*aCh*/,
virtual void GetCommonFallbackFonts(uint32_t /*aCh*/, uint32_t /*aNextCh*/,
int32_t /*aRunScript*/,
nsTArray<const char*>& /*aFontList*/)
{

View File

@ -536,7 +536,7 @@ gfxPlatformFontList::GetFontFamilyList(nsTArray<nsRefPtr<gfxFontFamily> >& aFami
}
gfxFontEntry*
gfxPlatformFontList::SystemFindFontForChar(const uint32_t aCh,
gfxPlatformFontList::SystemFindFontForChar(uint32_t aCh, uint32_t aNextCh,
int32_t aRunScript,
const gfxFontStyle* aStyle)
{
@ -570,7 +570,8 @@ gfxPlatformFontList::SystemFindFontForChar(const uint32_t aCh,
// search commonly available fonts
bool common = true;
gfxFontFamily *fallbackFamily = nullptr;
fontEntry = CommonFontFallback(aCh, aRunScript, aStyle, &fallbackFamily);
fontEntry = CommonFontFallback(aCh, aNextCh, aRunScript, aStyle,
&fallbackFamily);
// if didn't find a font, do system-wide fallback (except for specials)
uint32_t cmapCount = 0;
@ -638,7 +639,7 @@ gfxPlatformFontList::FindFontForCharProc(nsStringHashKey::KeyType aKey, nsRefPtr
#define NUM_FALLBACK_FONTS 8
gfxFontEntry*
gfxPlatformFontList::CommonFontFallback(const uint32_t aCh,
gfxPlatformFontList::CommonFontFallback(uint32_t aCh, uint32_t aNextCh,
int32_t aRunScript,
const gfxFontStyle* aMatchStyle,
gfxFontFamily** aMatchedFamily)
@ -646,7 +647,8 @@ gfxPlatformFontList::CommonFontFallback(const uint32_t aCh,
nsAutoTArray<const char*,NUM_FALLBACK_FONTS> defaultFallbacks;
uint32_t i, numFallbacks;
gfxPlatform::GetPlatform()->GetCommonFallbackFonts(aCh, aRunScript,
gfxPlatform::GetPlatform()->GetCommonFallbackFonts(aCh, aNextCh,
aRunScript,
defaultFallbacks);
numFallbacks = defaultFallbacks.Length();
for (i = 0; i < numFallbacks; i++) {

View File

@ -120,8 +120,8 @@ public:
virtual void GetFontFamilyList(nsTArray<nsRefPtr<gfxFontFamily> >& aFamilyArray);
virtual gfxFontEntry*
SystemFindFontForChar(const uint32_t aCh,
gfxFontEntry*
SystemFindFontForChar(uint32_t aCh, uint32_t aNextCh,
int32_t aRunScript,
const gfxFontStyle* aStyle);
@ -211,7 +211,7 @@ protected:
void* userArg);
// returns default font for a given character, null otherwise
gfxFontEntry* CommonFontFallback(const uint32_t aCh,
gfxFontEntry* CommonFontFallback(uint32_t aCh, uint32_t aNextCh,
int32_t aRunScript,
const gfxFontStyle* aMatchStyle,
gfxFontFamily** aMatchedFamily);

View File

@ -229,10 +229,14 @@ static const char kFontSTIXGeneral[] = "STIXGeneral";
static const char kFontTamilMN[] = "Tamil MN";
void
gfxPlatformMac::GetCommonFallbackFonts(const uint32_t aCh,
gfxPlatformMac::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
int32_t aRunScript,
nsTArray<const char*>& aFontList)
{
if (aNextCh == 0xfe0f) {
aFontList.AppendElement(kFontAppleColorEmoji);
}
aFontList.AppendElement(kFontLucidaGrande);
if (!IS_IN_BMP(aCh)) {

View File

@ -60,7 +60,7 @@ public:
nsTArray<nsString>& aListOfFonts);
nsresult UpdateFontList();
virtual void GetCommonFallbackFonts(const uint32_t aCh,
virtual void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
int32_t aRunScript,
nsTArray<const char*>& aFontList);

View File

@ -1884,7 +1884,8 @@ gfxFontGroup::MakeSpaceTextRun(const Parameters *aParams, uint32_t aFlags)
// find one that does.
uint8_t matchType;
nsRefPtr<gfxFont> spaceFont =
FindFontForChar(' ', 0, MOZ_SCRIPT_LATIN, nullptr, &matchType);
FindFontForChar(' ', 0, 0, MOZ_SCRIPT_LATIN, nullptr,
&matchType);
if (spaceFont) {
textRun->SetSpaceGlyph(spaceFont, aParams->mContext, 0,
orientation);
@ -2489,7 +2490,7 @@ gfxFontGroup::GetUnderlineOffset()
}
already_AddRefed<gfxFont>
gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, uint32_t aNextCh,
int32_t aRunScript, gfxFont *aPrevMatchedFont,
uint8_t *aMatchType)
{
@ -2649,7 +2650,7 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
// -- otherwise look for other stuff
*aMatchType = gfxTextRange::kSystemFallback;
font = WhichSystemFontSupportsChar(aCh, aRunScript);
font = WhichSystemFontSupportsChar(aCh, aNextCh, aRunScript);
return font.forget();
}
@ -2662,6 +2663,13 @@ void gfxFontGroup::ComputeRanges(nsTArray<gfxTextRange>& aRanges,
NS_ASSERTION(aLength > 0, "don't call ComputeRanges for zero-length text");
uint32_t prevCh = 0;
uint32_t nextCh = aString[0];
if (sizeof(T) == sizeof(char16_t)) {
if (aLength > 1 && NS_IS_HIGH_SURROGATE(nextCh) &&
NS_IS_LOW_SURROGATE(aString[1])) {
nextCh = SURROGATE_TO_UCS4(nextCh, aString[1]);
}
}
int32_t lastRangeIndex = -1;
// initialize prevFont to the group's primary font, so that this will be
@ -2678,15 +2686,28 @@ void gfxFontGroup::ComputeRanges(nsTArray<gfxTextRange>& aRanges,
const uint32_t origI = i; // save off in case we increase for surrogate
// set up current ch
uint32_t ch = aString[i];
uint32_t ch = nextCh;
// Get next char (if any) so that FindFontForChar can look ahead
// for a possible variation selector.
// in 16-bit case only, check for surrogate pair
if (sizeof(T) == sizeof(char16_t)) {
if ((i + 1 < aLength) && NS_IS_HIGH_SURROGATE(ch) &&
NS_IS_LOW_SURROGATE(aString[i + 1])) {
// In 16-bit case only, check for surrogate pairs.
if (ch > 0xffffu) {
i++;
ch = SURROGATE_TO_UCS4(ch, aString[i]);
}
if (i < aLength - 1) {
nextCh = aString[i + 1];
if ((i + 2 < aLength) && NS_IS_HIGH_SURROGATE(nextCh) &&
NS_IS_LOW_SURROGATE(aString[i + 2])) {
nextCh = SURROGATE_TO_UCS4(nextCh, aString[i + 2]);
}
} else {
nextCh = 0;
}
} else {
// 8-bit case is trivial.
nextCh = i < aLength - 1 ? aString[i + 1] : 0;
}
if (ch == 0xa0) {
@ -2695,7 +2716,8 @@ void gfxFontGroup::ComputeRanges(nsTArray<gfxTextRange>& aRanges,
// find the font for this char
nsRefPtr<gfxFont> font =
FindFontForChar(ch, prevCh, aRunScript, prevFont, &matchType);
FindFontForChar(ch, prevCh, nextCh, aRunScript, prevFont,
&matchType);
#ifndef RELEASE_BUILD
if (MOZ_UNLIKELY(mTextPerf)) {
@ -2931,11 +2953,12 @@ gfxFontGroup::WhichPrefFontSupportsChar(uint32_t aCh)
}
already_AddRefed<gfxFont>
gfxFontGroup::WhichSystemFontSupportsChar(uint32_t aCh, int32_t aRunScript)
gfxFontGroup::WhichSystemFontSupportsChar(uint32_t aCh, uint32_t aNextCh,
int32_t aRunScript)
{
gfxFontEntry *fe =
gfxPlatformFontList::PlatformFontList()->
SystemFindFontForChar(aCh, aRunScript, &mStyle);
SystemFindFontForChar(aCh, aNextCh, aRunScript, &mStyle);
if (fe) {
bool wantBold = mStyle.ComputeWeight() >= 6;
nsRefPtr<gfxFont> font =

View File

@ -818,15 +818,16 @@ public:
virtual gfxFloat GetUnderlineOffset();
virtual already_AddRefed<gfxFont>
FindFontForChar(uint32_t ch, uint32_t prevCh, int32_t aRunScript,
gfxFont *aPrevMatchedFont,
FindFontForChar(uint32_t ch, uint32_t prevCh, uint32_t aNextCh,
int32_t aRunScript, gfxFont *aPrevMatchedFont,
uint8_t *aMatchType);
// search through pref fonts for a character, return nullptr if no matching pref font
virtual already_AddRefed<gfxFont> WhichPrefFontSupportsChar(uint32_t aCh);
virtual already_AddRefed<gfxFont>
WhichSystemFontSupportsChar(uint32_t aCh, int32_t aRunScript);
already_AddRefed<gfxFont>
WhichSystemFontSupportsChar(uint32_t aCh, uint32_t aNextCh,
int32_t aRunScript);
template<typename T>
void ComputeRanges(nsTArray<gfxTextRange>& mRanges,

View File

@ -725,18 +725,29 @@ static const char kFontUtsaah[] = "Utsaah";
static const char kFontYuGothic[] = "Yu Gothic";
void
gfxWindowsPlatform::GetCommonFallbackFonts(const uint32_t aCh,
gfxWindowsPlatform::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
int32_t aRunScript,
nsTArray<const char*>& aFontList)
{
if (aNextCh == 0xfe0fu) {
aFontList.AppendElement(kFontSegoeUIEmoji);
}
// Arial is used as the default fallback for system fallback
aFontList.AppendElement(kFontArial);
if (!IS_IN_BMP(aCh)) {
uint32_t p = aCh >> 16;
if (p == 1) { // SMP plane
aFontList.AppendElement(kFontSegoeUIEmoji);
aFontList.AppendElement(kFontSegoeUISymbol);
if (aNextCh == 0xfe0eu) {
aFontList.AppendElement(kFontSegoeUISymbol);
aFontList.AppendElement(kFontSegoeUIEmoji);
} else {
if (aNextCh != 0xfe0fu) {
aFontList.AppendElement(kFontSegoeUIEmoji);
}
aFontList.AppendElement(kFontSegoeUISymbol);
}
aFontList.AppendElement(kFontEbrima);
aFontList.AppendElement(kFontNirmalaUI);
aFontList.AppendElement(kFontCambriaMath);
@ -814,7 +825,6 @@ gfxWindowsPlatform::GetCommonFallbackFonts(const uint32_t aCh,
case 0x2b:
case 0x2c:
aFontList.AppendElement(kFontSegoeUI);
aFontList.AppendElement(kFontSegoeUIEmoji);
aFontList.AppendElement(kFontSegoeUISymbol);
aFontList.AppendElement(kFontCambria);
aFontList.AppendElement(kFontMeiryo);

View File

@ -186,7 +186,7 @@ public:
nsresult UpdateFontList();
virtual void GetCommonFallbackFonts(const uint32_t aCh,
virtual void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
int32_t aRunScript,
nsTArray<const char*>& aFontList);

View File

@ -669,7 +669,7 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
// character is actually available.
uint8_t matchType;
nsRefPtr<gfxFont> mathFont = fontGroup->
FindFontForChar(ch2, 0, HB_SCRIPT_COMMON, nullptr, &matchType);
FindFontForChar(ch2, 0, 0, HB_SCRIPT_COMMON, nullptr, &matchType);
if (mathFont) {
// Don't apply the CSS style if there is a math font for at least one
// of the transformed character in this text run.