Bug 705594. Use CoreText for system font fallback on OSX. r=jfkthame

This commit is contained in:
John Daggett 2012-03-09 11:05:47 +09:00
Родитель 94e1fbc8c2
Коммит d2a5c3aea1
3 изменённых файлов: 110 добавлений и 1 удалений

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

@ -166,6 +166,7 @@ private:
friend class gfxPlatformMac; friend class gfxPlatformMac;
gfxMacPlatformFontList(); gfxMacPlatformFontList();
virtual ~gfxMacPlatformFontList();
// initialize font lists // initialize font lists
virtual nsresult InitFontList(); virtual nsresult InitFontList();
@ -181,12 +182,23 @@ private:
static void ATSNotification(ATSFontNotificationInfoRef aInfo, void* aUserArg); static void ATSNotification(ATSFontNotificationInfoRef aInfo, void* aUserArg);
// search fonts system-wide for a given character, null otherwise
virtual gfxFontEntry* GlobalFontFallback(const PRUint32 aCh,
PRInt32 aRunScript,
const gfxFontStyle* aMatchStyle,
PRUint32& aCmapCount);
virtual bool UsesSystemFallback() { return true; }
// keep track of ATS generation to prevent unneeded updates when loading downloaded fonts // keep track of ATS generation to prevent unneeded updates when loading downloaded fonts
PRUint32 mATSGeneration; PRUint32 mATSGeneration;
enum { enum {
kATSGenerationInitial = -1 kATSGenerationInitial = -1
}; };
// default font for use with system-wide font fallback
CTFontRef mDefaultFont;
}; };
#endif /* gfxMacPlatformFontList_H_ */ #endif /* gfxMacPlatformFontList_H_ */

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

@ -58,6 +58,7 @@
#include "nsDirectoryServiceUtils.h" #include "nsDirectoryServiceUtils.h"
#include "nsDirectoryServiceDefs.h" #include "nsDirectoryServiceDefs.h"
#include "nsISimpleEnumerator.h" #include "nsISimpleEnumerator.h"
#include "nsCharTraits.h"
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
@ -704,7 +705,8 @@ gfxSingleFaceMacFontFamily::ReadOtherFamilyNames(gfxPlatformFontList *aPlatformF
#pragma mark- #pragma mark-
gfxMacPlatformFontList::gfxMacPlatformFontList() : gfxMacPlatformFontList::gfxMacPlatformFontList() :
gfxPlatformFontList(false), mATSGeneration(PRUint32(kATSGenerationInitial)) gfxPlatformFontList(false), mATSGeneration(PRUint32(kATSGenerationInitial)),
mDefaultFont(nsnull)
{ {
::ATSFontNotificationSubscribe(ATSNotification, ::ATSFontNotificationSubscribe(ATSNotification,
kATSFontNotifyOptionDefault, kATSFontNotifyOptionDefault,
@ -719,6 +721,13 @@ gfxMacPlatformFontList::gfxMacPlatformFontList() :
sFontManager = [NSFontManager sharedFontManager]; sFontManager = [NSFontManager sharedFontManager];
} }
gfxMacPlatformFontList::~gfxMacPlatformFontList()
{
if (mDefaultFont) {
::CFRelease(mDefaultFont);
}
}
nsresult nsresult
gfxMacPlatformFontList::InitFontList() gfxMacPlatformFontList::InitFontList()
{ {
@ -875,6 +884,93 @@ gfxMacPlatformFontList::ATSNotification(ATSFontNotificationInfoRef aInfo,
qfc->UpdateFontList(); qfc->UpdateFontList();
} }
gfxFontEntry*
gfxMacPlatformFontList::GlobalFontFallback(const PRUint32 aCh,
PRInt32 aRunScript,
const gfxFontStyle* aMatchStyle,
PRUint32& aCmapCount)
{
bool useCmaps = gfxPlatform::GetPlatform()->UseCmapsDuringSystemFallback();
if (useCmaps) {
return gfxPlatformFontList::GlobalFontFallback(aCh,
aRunScript,
aMatchStyle,
aCmapCount);
}
CFStringRef str;
UniChar ch[2];
CFIndex len = 1;
if (IS_IN_BMP(aCh)) {
ch[0] = aCh;
str = ::CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, ch, 1,
kCFAllocatorNull);
} else {
ch[0] = H_SURROGATE(aCh);
ch[1] = L_SURROGATE(aCh);
str = ::CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, ch, 2,
kCFAllocatorNull);
if (!str) {
return nsnull;
}
len = 2;
}
// use CoreText to find the fallback family
gfxFontEntry *fontEntry = nsnull;
CTFontRef fallback;
bool cantUseFallbackFont = false;
if (!mDefaultFont) {
mDefaultFont = ::CTFontCreateWithName(CFSTR("Lucida Grande"), 12.f,
NULL);
}
fallback = ::CTFontCreateForString(mDefaultFont, str,
::CFRangeMake(0, len));
if (fallback) {
CFStringRef familyName = ::CTFontCopyFamilyName(fallback);
::CFRelease(fallback);
if (familyName &&
::CFStringCompare(familyName, CFSTR("LastResort"),
kCFCompareCaseInsensitive) != kCFCompareEqualTo)
{
nsAutoTArray<UniChar, 1024> buffer;
CFIndex len = ::CFStringGetLength(familyName);
buffer.SetLength(len+1);
::CFStringGetCharacters(familyName, ::CFRangeMake(0, len),
buffer.Elements());
buffer[len] = 0;
nsDependentString family(buffer.Elements(), len);
bool needsBold; // ignored in the system fallback case
fontEntry = FindFontForFamily(family, aMatchStyle, needsBold);
if (fontEntry && !fontEntry->TestCharacterMap(aCh)) {
fontEntry = nsnull;
cantUseFallbackFont = true;
}
}
if (familyName) {
::CFRelease(familyName);
}
}
if (cantUseFallbackFont) {
Telemetry::Accumulate(Telemetry::BAD_FALLBACK_FONT, cantUseFallbackFont);
}
::CFRelease(str);
return fontEntry;
}
gfxFontEntry* gfxFontEntry*
gfxMacPlatformFontList::GetDefaultFont(const gfxFontStyle* aStyle, bool& aNeedsBold) gfxMacPlatformFontList::GetDefaultFont(const gfxFontStyle* aStyle, bool& aNeedsBold)
{ {

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

@ -147,6 +147,7 @@ HISTOGRAM(WORD_CACHE_LOOKUP_SCRIPT, 1, 110, 111, LINEAR, "Word cache lookup (scr
HISTOGRAM(WORD_CACHE_HIT_SCRIPT, 1, 110, 111, LINEAR, "Word cache hit (script)") HISTOGRAM(WORD_CACHE_HIT_SCRIPT, 1, 110, 111, LINEAR, "Word cache hit (script)")
HISTOGRAM_BOOLEAN(FONT_CACHE_HIT, "font cache hit") HISTOGRAM_BOOLEAN(FONT_CACHE_HIT, "font cache hit")
HISTOGRAM_BOOLEAN(BAD_FALLBACK_FONT, "system fallback font can't be used")
HISTOGRAM_BOOLEAN(SHUTDOWN_OK, "Did the browser start after a successful shutdown") HISTOGRAM_BOOLEAN(SHUTDOWN_OK, "Did the browser start after a successful shutdown")