Merge backout of 98ea743c9156 (bug 463806) due to crashes on OS X 10.4 Talos boxes.

This commit is contained in:
Justin Dolske 2008-12-17 13:02:57 -08:00
Родитель 64fbb74a5c 8acba1c8ee
Коммит f2a8a199ed
2 изменённых файлов: 87 добавлений и 111 удалений

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

@ -85,9 +85,7 @@ public:
protected:
// for use with data fonts
MacOSFontEntry(const nsAString& aPostscriptName, ATSUFontID aFontID,
PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle,
gfxUserFontData *aUserFontData);
MacOSFontEntry(ATSUFontID aFontID, PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle, gfxUserFontData *aUserFontData);
PRUint32 mTraits;
MacOSFamilyEntry *mFamily;

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

@ -2,13 +2,12 @@
* ***** BEGIN LICENSE BLOCK *****
* Version: BSD
*
* Copyright (C) 2006-2008 Mozilla Corporation. All rights reserved.
* Copyright (C) 2006 Mozilla Corporation. All rights reserved.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com>
* Masayuki Nakano <masayuki@d-toybox.com>
* John Daggett <jdaggett@mozilla.com>
* Jonathan Kew <jfkthame@gmail.com>
*
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
*
@ -57,6 +56,11 @@
#include <unistd.h>
#include <time.h>
// _atsFontID is private; add it in our new category to NSFont
@interface NSFont (MozillaCategory)
- (ATSUFontID)_atsFontID;
@end
// font info loader constants
static const PRUint32 kDelayBeforeLoadingCmaps = 8 * 1000; // 8secs
static const PRUint32 kIntervalBetweenLoadingCmaps = 150; // 150ms
@ -113,7 +117,7 @@ gfxQuartzFontCache::GenerateFontListKey(const nsAString& aKeyName, nsAString& aR
#pragma mark-
MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName,
PRInt32 aAppleWeight, PRUint32 aTraits, MacOSFamilyEntry *aFamily)
PRInt32 aAppleWeight, PRUint32 aTraits, MacOSFamilyEntry *aFamily)
: gfxFontEntry(aPostscriptName), mTraits(aTraits), mFamily(aFamily), mATSUFontID(0),
mATSUIDInitialized(0)
{
@ -123,12 +127,10 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName,
mFixedPitch = (mTraits & NSFixedPitchFontMask ? 1 : 0);
}
MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, ATSUFontID aFontID,
PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle,
gfxUserFontData *aUserFontData)
MacOSFontEntry::MacOSFontEntry(ATSUFontID aFontID, PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle, gfxUserFontData *aUserFontData)
{
// xxx - stretch is basically ignored for now
mATSUIDInitialized = PR_TRUE;
mATSUFontID = aFontID;
mUserFontData = aUserFontData;
@ -141,7 +143,23 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, ATSUFontID aFon
(mFixedPitch ? NSFixedPitchFontMask : 0) |
(mWeight >= 600 ? NSBoldFontMask : NSUnboldFontMask);
mName = aPostscriptName;
// get the postscript name
OSStatus err;
NSString *psname = NULL;
// now lookup the Postscript name
err = ATSFontGetPostScriptName((ATSFontRef) aFontID, kATSOptionFlagsDefault, (CFStringRef*) (&psname));
if (err == noErr) {
GetStringForNSString(psname, mName);
[psname release];
} else {
mIsValid = PR_FALSE;
#ifdef DEBUG
char warnBuf[1024];
sprintf(warnBuf, "ATSFontGetPostScriptName err = %d", (PRInt32)err);
NS_WARNING(warnBuf);
#endif
}
}
const nsString&
@ -155,8 +173,8 @@ ATSUFontID MacOSFontEntry::GetFontID()
if (!mATSUIDInitialized) {
mATSUIDInitialized = PR_TRUE;
NSString *psname = GetNSStringForString(mName);
ATSFontRef fontRef = ATSFontFindFromPostScriptName((CFStringRef)psname, kATSOptionFlagsDefault);
mATSUFontID = FMGetFontFromATSFontRef(fontRef);
NSFont *font = [NSFont fontWithName:psname size:0.0];
if (font) mATSUFontID = [font _atsFontID];
}
return mATSUFontID;
}
@ -688,7 +706,7 @@ const PRUint32 kNonNormalTraits = NSItalicFontMask | NSBoldFontMask | NSNarrowFo
void
gfxQuartzFontCache::InitFontList()
{
ATSGeneration currentGeneration = ATSGetGeneration();
ATSGeneration currentGeneration = ATSGeneration();
// need to ignore notifications after adding each font
if (mATSGeneration == currentGeneration)
@ -1320,106 +1338,73 @@ gfxQuartzFontCache::MakePlatformFont(const gfxFontEntry *aProxyEntry,
return nsnull;
}
ATSFontRef fontRef;
ATSUFontID fontID;
ATSFontContainerRef containerRef;
// we get occasional failures when multiple fonts are activated in quick succession
// if the ATS font cache is damaged; to work around this, we can retry the activation
const PRUint32 kMaxRetries = 3;
PRUint32 retryCount = 0;
while (retryCount++ < kMaxRetries) {
err = ATSFontActivateFromMemory(const_cast<PRUint8*>(aFontData), aLength,
kPrivateATSFontContextPrivate,
kATSFontFormatUnspecified,
NULL,
kATSOptionFlagsDoNotNotify,
&containerRef);
mATSGeneration = ATSGetGeneration();
err = ATSFontActivateFromMemory(const_cast<PRUint8*>(aFontData), aLength,
kPrivateATSFontContextPrivate,
kATSFontFormatUnspecified,
NULL,
kATSOptionFlagsDoNotNotify,
&containerRef);
if (err != noErr) {
if (err != noErr) {
#if DEBUG
char warnBuf[1024];
const gfxProxyFontEntry *proxyEntry =
static_cast<const gfxProxyFontEntry*> (aProxyEntry);
sprintf(warnBuf, "downloaded font error, ATSFontActivateFromMemory err: %d for (%s)",
PRInt32(err),
NS_ConvertUTF16toUTF8(proxyEntry->mFamily->Name()).get());
NS_WARNING(warnBuf);
char warnBuf[1024];
const gfxProxyFontEntry *proxyEntry =
static_cast<const gfxProxyFontEntry*> (aProxyEntry);
sprintf(warnBuf, "downloaded font error, ATSFontActivateFromMemory err: %d for (%s)",
PRInt32(err),
NS_ConvertUTF16toUTF8(proxyEntry->mFamily->Name()).get());
NS_WARNING(warnBuf);
#endif
return nsnull;
}
return nsnull;
}
// ignoring containers with multiple fonts, use the first face only for now
err = ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1,
&fontRef, NULL);
if (err != noErr) {
mATSGeneration = ATSGeneration();
// ignoring containers with multiple fonts, use the first face only for now
err = ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1,
(ATSFontRef*)&fontID, NULL);
if (err != noErr) {
#if DEBUG
char warnBuf[1024];
const gfxProxyFontEntry *proxyEntry =
static_cast<const gfxProxyFontEntry*> (aProxyEntry);
sprintf(warnBuf, "downloaded font error, ATSFontFindFromContainer err: %d for (%s)",
PRInt32(err),
NS_ConvertUTF16toUTF8(proxyEntry->mFamily->Name()).get());
NS_WARNING(warnBuf);
char warnBuf[1024];
const gfxProxyFontEntry *proxyEntry =
static_cast<const gfxProxyFontEntry*> (aProxyEntry);
sprintf(warnBuf, "downloaded font error, ATSFontFindFromContainer err: %d for (%s)",
PRInt32(err),
NS_ConvertUTF16toUTF8(proxyEntry->mFamily->Name()).get());
NS_WARNING(warnBuf);
#endif
ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
return nsnull;
}
ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
return nsnull;
}
// now lookup the Postscript name; this may fail if the font cache is bad
OSStatus err;
NSString *psname = NULL;
nsAutoString postscriptName;
err = ATSFontGetPostScriptName(fontRef, kATSOptionFlagsDefault, (CFStringRef*) (&psname));
if (err == noErr) {
GetStringForNSString(psname, postscriptName);
[psname release];
} else {
#ifdef DEBUG
char warnBuf[1024];
const gfxProxyFontEntry *proxyEntry =
static_cast<const gfxProxyFontEntry*> (aProxyEntry);
sprintf(warnBuf, "ATSFontGetPostScriptName err = %d for (%s), retries = %d", (PRInt32)err,
NS_ConvertUTF16toUTF8(proxyEntry->mFamily->Name()).get(), retryCount);
NS_WARNING(warnBuf);
#endif
ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
// retry the activation a couple of times if this fails
// (may be a transient failure due to ATS font cache issues)
continue;
}
// font entry will own this
MacOSUserFontData *userFontData = new MacOSUserFontData(containerRef);
if (!userFontData) {
ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
return nsnull;
}
// font entry will own this
MacOSUserFontData *userFontData = new MacOSUserFontData(containerRef);
PRUint16 w = aProxyEntry->mWeight;
NS_ASSERTION(w >= 100 && w <= 900, "bogus font weight value!");
if (!userFontData) {
ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
return nsnull;
}
MacOSFontEntry *newFontEntry =
new MacOSFontEntry(fontID, w, aProxyEntry->mStretch,
(PRUint32(aProxyEntry->mItalic) ?
FONT_STYLE_ITALIC :
FONT_STYLE_NORMAL),
userFontData);
PRUint16 w = aProxyEntry->mWeight;
NS_ASSERTION(w >= 100 && w <= 900, "bogus font weight value!");
// create the font entry
MacOSFontEntry *newFontEntry =
new MacOSFontEntry(postscriptName,
FMGetFontFromATSFontRef(fontRef),
w, aProxyEntry->mStretch,
(PRUint32(aProxyEntry->mItalic) ?
FONT_STYLE_ITALIC :
FONT_STYLE_NORMAL),
userFontData);
if (!newFontEntry) {
delete userFontData;
return nsnull;
}
// if we succeeded (which should always be the case), return the new font
if (newFontEntry->mIsValid)
return newFontEntry;
// if something is funky about this font, delete immediately
if (!newFontEntry) {
delete userFontData;
return nsnull;
}
// if something is funky about this font, delete immediately
if (newFontEntry && !newFontEntry->mIsValid) {
#if DEBUG
char warnBuf[1024];
const gfxProxyFontEntry *proxyEntry =
@ -1429,17 +1414,10 @@ gfxQuartzFontCache::MakePlatformFont(const gfxFontEntry *aProxyEntry,
NS_WARNING(warnBuf);
#endif
delete newFontEntry;
// We don't retry from here; the ATS font cache issue would have caused failure earlier
// so if we get here, there's something else bad going on within our font data structures.
// Currently, there should be no way to reach here, as fontentry creation cannot fail
// except by memory allocation failure.
NS_WARNING("invalid font entry for a newly activated font");
break;
return nsnull;
}
// if we get here, the activation failed (even with possible retries); can't use this font
return nsnull;
return newFontEntry;
}