Bug 710727. Revert shared cmap patch due to reftest/mochitest-4 failures on Win7. a=bustage

This commit is contained in:
John Daggett 2012-04-09 22:03:28 +09:00
parent e641d58724
commit 7b5ada3029
10 changed files with 180 additions and 426 deletions

View File

@ -375,78 +375,84 @@ gfxDWriteFontEntry::ReadCMAP()
nsresult rv;
// attempt this once, if errors occur leave a blank cmap
if (mCharacterMap) {
if (mCmapInitialized)
return NS_OK;
}
nsRefPtr<gfxCharacterMap> charmap = new gfxCharacterMap();
mCmapInitialized = true;
// if loading via GDI, just use GetFontTable
if (mFont && gfxDWriteFontList::PlatformFontList()->UseGDIFontTableAccess()) {
PRUint32 kCMAP = TRUETYPE_TAG('c','m','a','p');
nsresult rv;
const PRUint32 kCmapTag = TRUETYPE_TAG('c','m','a','p');
AutoFallibleTArray<PRUint8,16384> buffer;
AutoFallibleTArray<PRUint8,16384> cmap;
rv = GetFontTable(kCMAP, cmap);
if (GetFontTable(kCmapTag, buffer) != NS_OK)
return NS_ERROR_FAILURE;
PRUint8 *cmap = buffer.Elements();
bool unicodeFont = false, symbolFont = false; // currently ignored
if (NS_SUCCEEDED(rv)) {
rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(),
*charmap, mUVSOffset,
unicodeFont, symbolFont);
}
} else {
// loading using dwrite, don't use GetFontTable to avoid copy
nsRefPtr<IDWriteFontFace> fontFace;
rv = CreateFontFace(getter_AddRefs(fontFace));
if (NS_SUCCEEDED(rv)) {
const PRUint32 kCmapTag = DWRITE_MAKE_OPENTYPE_TAG('c', 'm', 'a', 'p');
PRUint8 *tableData;
PRUint32 len;
void *tableContext = NULL;
BOOL exists;
hr = fontFace->TryGetFontTable(kCmapTag, (const void**)&tableData,
&len, &tableContext, &exists);
if (SUCCEEDED(hr)) {
bool isSymbol = fontFace->IsSymbolFont();
bool isUnicode = true;
if (exists) {
rv = gfxFontUtils::ReadCMAP(tableData, len, *charmap,
mUVSOffset, isUnicode,
isSymbol);
}
fontFace->ReleaseFontTable(tableContext);
} else {
rv = NS_ERROR_FAILURE;
}
bool unicodeFont = false, symbolFont = false;
rv = gfxFontUtils::ReadCMAP(cmap, buffer.Length(),
mCharacterMap, mUVSOffset,
unicodeFont, symbolFont);
#ifdef PR_LOGGING
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
NS_ConvertUTF16toUTF8(mName).get(),
mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
if (LOG_CMAPDATA_ENABLED()) {
char prefix[256];
sprintf(prefix, "(cmapdata) name: %.220s",
NS_ConvertUTF16toUTF8(mName).get());
mCharacterMap.Dump(prefix, eGfxLog_cmapdata);
}
#endif
mHasCmapTable = NS_SUCCEEDED(rv);
return rv;
}
mHasCmapTable = NS_SUCCEEDED(rv);
if (mHasCmapTable) {
gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
mCharacterMap = pfl->FindCharMap(charmap);
} else {
// if error occurred, initialize to null cmap
mCharacterMap = new gfxCharacterMap();
// loading using dwrite, don't use GetFontTable to avoid copy
nsRefPtr<IDWriteFontFace> fontFace;
rv = CreateFontFace(getter_AddRefs(fontFace));
if (NS_FAILED(rv)) {
return rv;
}
PRUint8 *tableData;
PRUint32 len;
void *tableContext = NULL;
BOOL exists;
hr = fontFace->TryGetFontTable(DWRITE_MAKE_OPENTYPE_TAG('c', 'm', 'a', 'p'),
(const void**)&tableData,
&len,
&tableContext,
&exists);
if (FAILED(hr)) {
return NS_ERROR_FAILURE;
}
bool isSymbol = fontFace->IsSymbolFont();
bool isUnicode = true;
if (exists) {
rv = gfxFontUtils::ReadCMAP(tableData,
len,
mCharacterMap,
mUVSOffset,
isUnicode,
isSymbol);
}
fontFace->ReleaseFontTable(tableContext);
#ifdef PR_LOGGING
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d hash: %8.8x%s\n",
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
NS_ConvertUTF16toUTF8(mName).get(),
charmap->SizeOfIncludingThis(moz_malloc_size_of),
charmap->mHash, mCharacterMap == charmap ? " new" : ""));
mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
if (LOG_CMAPDATA_ENABLED()) {
char prefix[256];
sprintf(prefix, "(cmapdata) name: %.220s",
NS_ConvertUTF16toUTF8(mName).get());
charmap->Dump(prefix, eGfxLog_cmapdata);
mCharacterMap.Dump(prefix, eGfxLog_cmapdata);
}
#endif
mHasCmapTable = NS_SUCCEEDED(rv);
return rv;
}

View File

@ -343,11 +343,12 @@ FT2FontEntry::CairoFontFace()
nsresult
FT2FontEntry::ReadCMAP()
{
if (mCharacterMap) {
if (mCmapInitialized) {
return NS_OK;
}
nsRefPtr<gfxCharacterMap> charmap = new gfxCharacterMap();
// attempt this once, if errors occur leave a blank cmap
mCmapInitialized = true;
AutoFallibleTArray<PRUint8,16384> buffer;
nsresult rv = GetFontTable(TTAG_cmap, buffer);
@ -356,18 +357,11 @@ FT2FontEntry::ReadCMAP()
bool unicodeFont;
bool symbolFont;
rv = gfxFontUtils::ReadCMAP(buffer.Elements(), buffer.Length(),
*charmap, mUVSOffset,
mCharacterMap, mUVSOffset,
unicodeFont, symbolFont);
}
mHasCmapTable = NS_SUCCEEDED(rv);
if (mHasCmapTable) {
gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
mCharacterMap = pfl->FindCharMap(charmap);
} else {
// if error occurred, initialize to null cmap
mCharacterMap = new gfxCharacterMap();
}
return rv;
}

View File

@ -103,16 +103,6 @@ static PRUint32 gGlyphExtentsSetupLazyTight = 0;
static PRUint32 gGlyphExtentsSetupFallBackToTight = 0;
#endif
void
gfxCharacterMap::NotifyReleased()
{
gfxPlatformFontList *fontlist = gfxPlatformFontList::PlatformFontList();
if (mShared) {
fontlist->RemoveCmap(this);
}
delete this;
}
gfxFontEntry::~gfxFontEntry()
{
delete mUserFontData;
@ -125,20 +115,18 @@ bool gfxFontEntry::IsSymbolFont()
bool gfxFontEntry::TestCharacterMap(PRUint32 aCh)
{
if (!mCharacterMap) {
if (!mCmapInitialized) {
ReadCMAP();
NS_ASSERTION(mCharacterMap, "failed to initialize character map");
}
return mCharacterMap->test(aCh);
return mCharacterMap.test(aCh);
}
nsresult gfxFontEntry::InitializeUVSMap()
{
// mUVSOffset will not be initialized
// until cmap is initialized.
if (!mCharacterMap) {
if (!mCmapInitialized) {
ReadCMAP();
NS_ASSERTION(mCharacterMap, "failed to initialize character map");
}
if (!mUVSOffset) {
@ -182,8 +170,7 @@ PRUint16 gfxFontEntry::GetUVSGlyph(PRUint32 aCh, PRUint32 aVS)
nsresult gfxFontEntry::ReadCMAP()
{
NS_ASSERTION(false, "using default no-op implementation of ReadCMAP");
mCharacterMap = new gfxCharacterMap();
mCmapInitialized = true;
return NS_OK;
}
@ -446,12 +433,7 @@ gfxFontEntry::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize += mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
// cmaps are shared so only non-shared cmaps are included here
if (mCharacterMap && mCharacterMap->mBuildOnTheFly) {
aSizes->mCharMapsSize +=
mCharacterMap->SizeOfIncludingThis(aMallocSizeOf);
}
aSizes->mCharMapsSize += mCharacterMap.SizeOfExcludingThis(aMallocSizeOf);
aSizes->mFontTableCacheSize +=
mFontTableCache.SizeOfExcludingThis(
FontTableHashEntry::SizeOfEntryExcludingThis,
@ -788,7 +770,7 @@ CalcStyleMatch(gfxFontEntry *aFontEntry, const gfxFontStyle *aStyle)
void
gfxFontFamily::FindFontForChar(GlobalFontMatch *aMatchData)
{
if (mFamilyCharacterMapInitialized && !TestCharacterMap(aMatchData->mCh)) {
if (mCharacterMapInitialized && !TestCharacterMap(aMatchData->mCh)) {
// none of the faces in the family support the required char,
// so bail out immediately
return;
@ -1046,8 +1028,7 @@ gfxFontFamily::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
{
aSizes->mFontListSize +=
mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
aSizes->mCharMapsSize +=
mFamilyCharacterMap.SizeOfExcludingThis(aMallocSizeOf);
aSizes->mCharMapsSize += mCharacterMap.SizeOfExcludingThis(aMallocSizeOf);
aSizes->mFontListSize +=
mAvailableFonts.SizeOfExcludingThis(aMallocSizeOf);
@ -3666,9 +3647,7 @@ gfxFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh,
// check other faces of the family
gfxFontFamily *family = font->GetFontEntry()->Family();
if (family && !font->GetFontEntry()->mIsProxy &&
family->TestCharacterMap(aCh))
{
if (family && family->TestCharacterMap(aCh)) {
GlobalFontMatch matchData(aCh, aRunScript, &mStyle);
family->SearchAllFontsForChar(&matchData);
gfxFontEntry *fe = matchData.mBestMatch;

View File

@ -198,56 +198,6 @@ struct THEBES_API gfxFontStyle {
static PRUint32 ParseFontLanguageOverride(const nsString& aLangTag);
};
class gfxCharacterMap : public gfxSparseBitSet {
public:
nsrefcnt AddRef() {
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
++mRefCnt;
NS_LOG_ADDREF(this, mRefCnt, "gfxCharacterMap", sizeof(*this));
return mRefCnt;
}
nsrefcnt Release() {
NS_PRECONDITION(0 != mRefCnt, "dup release");
--mRefCnt;
NS_LOG_RELEASE(this, mRefCnt, "gfxCharacterMap");
if (mRefCnt == 0) {
NotifyReleased();
// |this| has been deleted.
return 0;
}
return mRefCnt;
}
gfxCharacterMap() :
mHash(0), mBuildOnTheFly(false), mShared(false)
{ }
void CalcHash() { mHash = GetChecksum(); }
size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
return gfxSparseBitSet::SizeOfExcludingThis(aMallocSizeOf);
}
// hash of the cmap bitvector
PRUint32 mHash;
// if cmap is built on the fly it's never shared
bool mBuildOnTheFly;
// cmap is shared globally
bool mShared;
protected:
void NotifyReleased();
nsAutoRefCnt mRefCnt;
private:
gfxCharacterMap(const gfxCharacterMap&);
gfxCharacterMap& operator=(const gfxCharacterMap&);
};
class gfxFontEntry {
public:
NS_INLINE_DECL_REFCOUNTING(gfxFontEntry)
@ -266,6 +216,7 @@ public:
mCheckedForGraphiteTables(false),
#endif
mHasCmapTable(false),
mCmapInitialized(false),
mUVSOffset(0), mUVSData(nsnull),
mUserFontData(nsnull),
mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE),
@ -308,17 +259,16 @@ public:
#endif
inline bool HasCmapTable() {
if (!mCharacterMap) {
if (!mCmapInitialized) {
ReadCMAP();
NS_ASSERTION(mCharacterMap, "failed to initialize character map");
}
return mHasCmapTable;
}
inline bool HasCharacter(PRUint32 ch) {
if (mCharacterMap && mCharacterMap->test(ch)) {
if (mCharacterMap.test(ch))
return true;
}
return TestCharacterMap(ch);
}
@ -394,7 +344,8 @@ public:
bool mCheckedForGraphiteTables;
#endif
bool mHasCmapTable;
nsRefPtr<gfxCharacterMap> mCharacterMap;
bool mCmapInitialized;
gfxSparseBitSet mCharacterMap;
PRUint32 mUVSOffset;
nsAutoArrayPtr<PRUint8> mUVSData;
gfxUserFontData* mUserFontData;
@ -424,6 +375,7 @@ protected:
mCheckedForGraphiteTables(false),
#endif
mHasCmapTable(false),
mCmapInitialized(false),
mUVSOffset(0), mUVSData(nsnull),
mUserFontData(nsnull),
mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE),
@ -577,7 +529,7 @@ public:
mHasStyles(false),
mIsSimpleFamily(false),
mIsBadUnderlineFamily(false),
mFamilyCharacterMapInitialized(false)
mCharacterMapInitialized(false)
{ }
virtual ~gfxFontFamily() {
@ -655,27 +607,26 @@ public:
PRUint32 i, numFonts = mAvailableFonts.Length();
for (i = 0; i < numFonts; i++) {
gfxFontEntry *fe = mAvailableFonts[i];
// don't try to load cmaps for downloadable fonts not yet loaded
if (!fe || fe->mIsProxy) {
if (!fe) {
continue;
}
fe->ReadCMAP();
mFamilyCharacterMap.Union(*(fe->mCharacterMap));
mCharacterMap.Union(fe->mCharacterMap);
}
mFamilyCharacterMap.Compact();
mFamilyCharacterMapInitialized = true;
mCharacterMap.Compact();
mCharacterMapInitialized = true;
}
bool TestCharacterMap(PRUint32 aCh) {
if (!mFamilyCharacterMapInitialized) {
if (!mCharacterMapInitialized) {
ReadAllCMAPs();
}
return mFamilyCharacterMap.test(aCh);
return mCharacterMap.test(aCh);
}
void ResetCharacterMap() {
mFamilyCharacterMap.reset();
mFamilyCharacterMapInitialized = false;
mCharacterMap.reset();
mCharacterMapInitialized = false;
}
// mark this family as being in the "bad" underline offset blacklist
@ -724,14 +675,14 @@ protected:
nsString mName;
nsTArray<nsRefPtr<gfxFontEntry> > mAvailableFonts;
gfxSparseBitSet mFamilyCharacterMap;
bool mOtherFamilyNamesInitialized : 1;
bool mHasOtherFamilyNames : 1;
bool mFaceNamesInitialized : 1;
bool mHasStyles : 1;
bool mIsSimpleFamily : 1;
bool mIsBadUnderlineFamily : 1;
bool mFamilyCharacterMapInitialized : 1;
gfxSparseBitSet mCharacterMap;
bool mOtherFamilyNamesInitialized;
bool mHasOtherFamilyNames;
bool mFaceNamesInitialized;
bool mHasStyles;
bool mIsSimpleFamily;
bool mIsBadUnderlineFamily;
bool mCharacterMapInitialized;
enum {
// for "simple" families, the faces are stored in mAvailableFonts

View File

@ -58,8 +58,6 @@
#include "nsAutoPtr.h"
#include "nsIStreamBufferAccess.h"
#include "zlib.h"
/* Bug 341128 - w32api defines min/max which causes problems with <bitset> */
#ifdef __MINGW32__
#undef min
@ -89,28 +87,6 @@ public:
mBlocks[i] = new Block(*block);
}
}
bool Equals(const gfxSparseBitSet *aOther) const {
if (mBlocks.Length() != aOther->mBlocks.Length()) {
return false;
}
size_t n = mBlocks.Length();
for (size_t i = 0; i < n; ++i) {
const Block *b1 = mBlocks[i];
const Block *b2 = aOther->mBlocks[i];
if (!b1 != !b2) {
return false;
}
if (!b1) {
continue;
}
if (memcmp(&b1->mBits, &b2->mBits, BLOCK_SIZE) != 0) {
return false;
}
}
return true;
}
bool test(PRUint32 aIndex) const {
NS_ASSERTION(mBlocks.DebugGetHeader(), "mHdr is null, this is bad");
PRUint32 blockIndex = aIndex/BLOCK_SIZE_BITS;
@ -345,18 +321,6 @@ public:
mBlocks.Compact();
}
PRUint32 GetChecksum() const {
PRUint32 check = adler32(0, Z_NULL, 0);
for (PRUint32 i = 0; i < mBlocks.Length(); i++) {
if (mBlocks[i]) {
const Block *block = mBlocks[i];
check = adler32(check, (PRUint8*) (&i), 4);
check = adler32(check, (PRUint8*) block, sizeof(Block));
}
}
return check;
}
private:
nsTArray< nsAutoPtr<Block> > mBlocks;
};

View File

@ -201,7 +201,7 @@ GDIFontEntry::GDIFontEntry(const nsAString& aFaceName,
: gfxFontEntry(aFaceName),
mWindowsFamily(0), mWindowsPitch(0),
mFontType(aFontType),
mForceGDI(false),
mForceGDI(false), mUnknownCMAP(false),
mCharset(), mUnicodeRanges()
{
mUserFontData = aUserFontData;
@ -218,62 +218,43 @@ GDIFontEntry::GDIFontEntry(const nsAString& aFaceName,
nsresult
GDIFontEntry::ReadCMAP()
{
// attempt this once, if errors occur leave a blank cmap
if (mCharacterMap) {
return NS_OK;
}
// skip non-SFNT fonts completely
if (mFontType != GFX_FONT_TYPE_PS_OPENTYPE &&
mFontType != GFX_FONT_TYPE_TT_OPENTYPE &&
mFontType != GFX_FONT_TYPE_TRUETYPE)
{
mCharacterMap = new gfxCharacterMap();
return NS_ERROR_FAILURE;
}
nsRefPtr<gfxCharacterMap> charmap = new gfxCharacterMap();
// attempt this once, if errors occur leave a blank cmap
if (mCmapInitialized)
return NS_OK;
mCmapInitialized = true;
PRUint32 kCMAP = TRUETYPE_TAG('c','m','a','p');
nsresult rv;
const PRUint32 kCmapTag = TRUETYPE_TAG('c','m','a','p');
AutoFallibleTArray<PRUint8,16384> buffer;
if (GetFontTable(kCmapTag, buffer) != NS_OK)
return NS_ERROR_FAILURE;
PRUint8 *cmap = buffer.Elements();
AutoFallibleTArray<PRUint8,16384> cmap;
rv = GetFontTable(kCMAP, cmap);
bool unicodeFont = false, symbolFont = false; // currently ignored
if (NS_SUCCEEDED(rv)) {
rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(),
*charmap, mUVSOffset,
unicodeFont, symbolFont);
}
bool unicodeFont = false, symbolFont = false;
nsresult rv = gfxFontUtils::ReadCMAP(cmap, buffer.Length(),
mCharacterMap, mUVSOffset,
unicodeFont, symbolFont);
mSymbolFont = symbolFont;
mHasCmapTable = NS_SUCCEEDED(rv);
if (mHasCmapTable) {
gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
mCharacterMap = pfl->FindCharMap(charmap);
} else {
// if error occurred, initialize to null cmap
mCharacterMap = new gfxCharacterMap();
// For fonts where we failed to read the character map,
// we can take a slow path to look up glyphs character by character
mCharacterMap->mBuildOnTheFly = true;
}
#ifdef PR_LOGGING
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d hash: %8.8x%s\n",
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
NS_ConvertUTF16toUTF8(mName).get(),
charmap->SizeOfIncludingThis(moz_malloc_size_of),
charmap->mHash, mCharacterMap == charmap ? " new" : ""));
mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
if (LOG_CMAPDATA_ENABLED()) {
char prefix[256];
sprintf(prefix, "(cmapdata) name: %.220s",
NS_ConvertUTF16toUTF8(mName).get());
charmap->Dump(prefix, eGfxLog_cmapdata);
mCharacterMap.Dump(prefix, eGfxLog_cmapdata);
}
#endif
return rv;
}
@ -365,12 +346,13 @@ GDIFontEntry::FillLogFont(LOGFONTW *aLogFont,
bool
GDIFontEntry::TestCharacterMap(PRUint32 aCh)
{
if (!mCharacterMap) {
nsresult rv = ReadCMAP();
NS_ASSERTION(mCharacterMap, "failed to initialize a character map");
if (ReadCMAP() != NS_OK) {
// For fonts where we failed to read the character map,
// we can take a slow path to look up glyphs character by character
mUnknownCMAP = true;
}
if (mCharacterMap->mBuildOnTheFly) {
if (mUnknownCMAP) {
if (aCh > 0xFFFF)
return false;
@ -422,12 +404,12 @@ GDIFontEntry::TestCharacterMap(PRUint32 aCh)
ReleaseDC(NULL, dc);
if (hasGlyph) {
mCharacterMap->set(aCh);
mCharacterMap.set(aCh);
return true;
}
} else {
// font had a cmap so simply check that
return mCharacterMap->test(aCh);
return mCharacterMap.test(aCh);
}
return false;

View File

@ -293,6 +293,7 @@ public:
gfxWindowsFontType mFontType;
bool mForceGDI : 1;
bool mUnknownCMAP : 1;
gfxSparseBitSet mCharset;
gfxSparseBitSet mUnicodeRanges;

View File

@ -189,98 +189,93 @@ nsresult
MacOSFontEntry::ReadCMAP()
{
// attempt this once, if errors occur leave a blank cmap
if (mCharacterMap) {
if (mCmapInitialized) {
return NS_OK;
}
nsRefPtr<gfxCharacterMap> charmap = new gfxCharacterMap();
mCmapInitialized = true;
PRUint32 kCMAP = TRUETYPE_TAG('c','m','a','p');
nsresult rv;
AutoFallibleTArray<PRUint8,16384> cmap;
rv = GetFontTable(kCMAP, cmap);
bool unicodeFont = false, symbolFont = false; // currently ignored
if (NS_SUCCEEDED(rv)) {
rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(),
*charmap, mUVSOffset,
unicodeFont, symbolFont);
if (GetFontTable(kCMAP, cmap) != NS_OK) {
return NS_ERROR_FAILURE;
}
if (NS_SUCCEEDED(rv)) {
// for layout support, check for the presence of mort/morx and/or
// opentype layout tables
bool hasAATLayout = HasFontTable(TRUETYPE_TAG('m','o','r','x')) ||
HasFontTable(TRUETYPE_TAG('m','o','r','t'));
bool hasGSUB = HasFontTable(TRUETYPE_TAG('G','S','U','B'));
bool hasGPOS = HasFontTable(TRUETYPE_TAG('G','P','O','S'));
bool unicodeFont, symbolFont; // currently ignored
nsresult rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(),
mCharacterMap, mUVSOffset,
unicodeFont, symbolFont);
if (NS_FAILED(rv)) {
mCharacterMap.reset();
return rv;
}
mHasCmapTable = true;
if (hasAATLayout && !(hasGSUB || hasGPOS)) {
mRequiresAAT = true; // prefer CoreText if font has no OTL tables
}
CGFontRef fontRef = GetFontRef();
if (!fontRef) {
return NS_ERROR_FAILURE;
}
PRUint32 numScripts =
sizeof(gScriptsThatRequireShaping) / sizeof(ScriptRange);
// for layout support, check for the presence of mort/morx and/or
// opentype layout tables
bool hasAATLayout = HasFontTable(TRUETYPE_TAG('m','o','r','x')) ||
HasFontTable(TRUETYPE_TAG('m','o','r','t'));
bool hasGSUB = HasFontTable(TRUETYPE_TAG('G','S','U','B'));
bool hasGPOS = HasFontTable(TRUETYPE_TAG('G','P','O','S'));
for (PRUint32 s = 0; s < numScripts; s++) {
eComplexScript whichScript = gScriptsThatRequireShaping[s].script;
if (hasAATLayout && !(hasGSUB || hasGPOS)) {
mRequiresAAT = true; // prefer CoreText if font has no OTL tables
}
// check to see if the cmap includes complex script codepoints
if (charmap->TestRange(gScriptsThatRequireShaping[s].rangeStart,
gScriptsThatRequireShaping[s].rangeEnd)) {
bool omitRange = true;
PRUint32 numScripts =
sizeof(gScriptsThatRequireShaping) / sizeof(ScriptRange);
if (hasAATLayout) {
for (PRUint32 s = 0; s < numScripts; s++) {
eComplexScript whichScript = gScriptsThatRequireShaping[s].script;
// check to see if the cmap includes complex script codepoints
if (mCharacterMap.TestRange(gScriptsThatRequireShaping[s].rangeStart,
gScriptsThatRequireShaping[s].rangeEnd)) {
bool omitRange = true;
if (hasAATLayout) {
omitRange = false;
// prefer CoreText for Apple's complex-script fonts,
// even if they also have some OpenType tables
// (e.g. Geeza Pro Bold on 10.6; see bug 614903)
mRequiresAAT = true;
} else if (whichScript == eComplexScriptArabic) {
// special-case for Arabic:
// even if there's no morph table, CoreText can shape Arabic
// using OpenType layout; or if it's a downloaded font,
// assume the site knows what it's doing (as harfbuzz will
// be able to shape even though the font itself lacks tables
// stripped during sanitization).
// We check for GSUB here, as GPOS alone would not be ok
// for Arabic shaping.
if (hasGSUB || (mIsUserFont && !mIsLocalUserFont)) {
// TODO: to be really thorough, we could check that the
// GSUB table actually supports the 'arab' script tag.
omitRange = false;
// prefer CoreText for Apple's complex-script fonts,
// even if they also have some OpenType tables
// (e.g. Geeza Pro Bold on 10.6; see bug 614903)
mRequiresAAT = true;
} else if (whichScript == eComplexScriptArabic) {
// special-case for Arabic:
// even if there's no morph table, CoreText can shape Arabic
// using OpenType layout; or if it's a downloaded font,
// assume the site knows what it's doing (as harfbuzz will
// be able to shape even though the font itself lacks tables
// stripped during sanitization).
// We check for GSUB here, as GPOS alone would not be ok
// for Arabic shaping.
if (hasGSUB || (mIsUserFont && !mIsLocalUserFont)) {
// TODO: to be really thorough, we could check that the
// GSUB table actually supports the 'arab' script tag.
omitRange = false;
}
}
}
if (omitRange) {
charmap->ClearRange(gScriptsThatRequireShaping[s].rangeStart,
gScriptsThatRequireShaping[s].rangeEnd);
}
if (omitRange) {
mCharacterMap.ClearRange(gScriptsThatRequireShaping[s].rangeStart,
gScriptsThatRequireShaping[s].rangeEnd);
}
}
}
mHasCmapTable = NS_SUCCEEDED(rv);
if (mHasCmapTable) {
gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
mCharacterMap = pfl->FindCharMap(charmap);
} else {
// if error occurred, initialize to null cmap
mCharacterMap = new gfxCharacterMap();
}
#ifdef PR_LOGGING
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d hash: %8.8x%s\n",
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
NS_ConvertUTF16toUTF8(mName).get(),
charmap->SizeOfIncludingThis(moz_malloc_size_of),
charmap->mHash, mCharacterMap == charmap ? " new" : ""));
mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
if (LOG_CMAPDATA_ENABLED()) {
char prefix[256];
sprintf(prefix, "(cmapdata) name: %.220s",
NS_ConvertUTF16toUTF8(mName).get());
charmap->Dump(prefix, eGfxLog_cmapdata);
mCharacterMap.Dump(prefix, eGfxLog_cmapdata);
}
#endif

View File

@ -213,13 +213,10 @@ gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames)
gFontListPrefObserver = new gfxFontListPrefObserver();
NS_ADDREF(gFontListPrefObserver);
Preferences::AddStrongObservers(gFontListPrefObserver, kObservedPrefs);
mSharedCmaps.Init(16);
}
gfxPlatformFontList::~gfxPlatformFontList()
{
mSharedCmaps.Clear();
NS_ASSERTION(gFontListPrefObserver, "There is no font list pref observer");
Preferences::RemoveObservers(gFontListPrefObserver, kObservedPrefs);
NS_RELEASE(gFontListPrefObserver);
@ -717,41 +714,6 @@ gfxPlatformFontList::GetStandardFamilyName(const nsAString& aFontName, nsAString
return !aFamilyName.IsEmpty();
}
gfxCharacterMap*
gfxPlatformFontList::FindCharMap(gfxCharacterMap *aCmap)
{
aCmap->CalcHash();
gfxCharacterMap *cmap = AddCmap(aCmap);
cmap->mShared = true;
return cmap;
}
// add a cmap to the shared cmap set
gfxCharacterMap*
gfxPlatformFontList::AddCmap(const gfxCharacterMap* aCharMap)
{
CharMapHashKey *found =
mSharedCmaps.PutEntry(const_cast<gfxCharacterMap*>(aCharMap));
return found->GetKey();
}
// remove the cmap from the shared cmap set
void
gfxPlatformFontList::RemoveCmap(const gfxCharacterMap* aCharMap)
{
// skip lookups during teardown
if (mSharedCmaps.Count() == 0) {
return;
}
// cmap needs to match the entry *and* be the same ptr before removing
CharMapHashKey *found =
mSharedCmaps.GetEntry(const_cast<gfxCharacterMap*>(aCharMap));
if (found && found->GetKey() == aCharMap) {
mSharedCmaps.RemoveEntry(const_cast<gfxCharacterMap*>(aCharMap));
}
}
void
gfxPlatformFontList::InitLoader()
{
@ -868,21 +830,6 @@ SizeOfStringEntryExcludingThis(nsStringHashKey* aHashEntry,
return aHashEntry->GetKey().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
static size_t
SizeOfSharedCmapExcludingThis(CharMapHashKey* aHashEntry,
nsMallocSizeOfFun aMallocSizeOf,
void* aUserArg)
{
FontListSizes *sizes = static_cast<FontListSizes*>(aUserArg);
PRUint32 size = aHashEntry->GetKey()->SizeOfIncludingThis(aMallocSizeOf);
sizes->mCharMapsSize += size;
// we return zero here because the measurements have been added directly
// to the relevant fields of the FontListSizes record
return 0;
}
void
gfxPlatformFontList::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
@ -918,10 +865,6 @@ gfxPlatformFontList::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
aSizes->mFontListSize +=
mBadUnderlineFamilyNames.SizeOfExcludingThis(SizeOfStringEntryExcludingThis,
aMallocSizeOf);
aSizes->mFontListSize +=
mSharedCmaps.SizeOfExcludingThis(SizeOfSharedCmapExcludingThis,
aMallocSizeOf, aSizes);
}
void

View File

@ -50,53 +50,6 @@
#include "nsIMemoryReporter.h"
#include "mozilla/FunctionTimer.h"
class CharMapHashKey : public PLDHashEntryHdr
{
public:
typedef gfxCharacterMap* KeyType;
typedef const gfxCharacterMap* KeyTypePointer;
CharMapHashKey(const gfxCharacterMap *aCharMap) :
mCharMap(const_cast<gfxCharacterMap*>(aCharMap))
{
MOZ_COUNT_CTOR(CharMapHashKey);
}
CharMapHashKey(const CharMapHashKey& toCopy) :
mCharMap(toCopy.mCharMap)
{
MOZ_COUNT_CTOR(CharMapHashKey);
}
~CharMapHashKey()
{
MOZ_COUNT_DTOR(CharMapHashKey);
}
gfxCharacterMap* GetKey() const { return mCharMap; }
bool KeyEquals(const gfxCharacterMap *aCharMap) const {
NS_ASSERTION(!aCharMap->mBuildOnTheFly && !mCharMap->mBuildOnTheFly,
"custom cmap used in shared cmap hashtable");
// cmaps built on the fly never match
if (aCharMap->mHash != mCharMap->mHash)
{
return false;
}
return mCharMap->Equals(aCharMap);
}
static const gfxCharacterMap* KeyToPointer(gfxCharacterMap *aCharMap) {
return aCharMap;
}
static PLDHashNumber HashKey(const gfxCharacterMap *aCharMap) {
return aCharMap->mHash;
}
enum { ALLOW_MEMMOVE = true };
protected:
gfxCharacterMap *mCharMap;
};
// gfxPlatformFontList is an abstract class for the global font list on the system;
// concrete subclasses for each platform implement the actual interface to the system fonts.
// This class exists because we cannot rely on the platform font-finding APIs to behave
@ -202,16 +155,6 @@ public:
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
// search for existing cmap that matches the input
// return the input if no match is found
gfxCharacterMap* FindCharMap(gfxCharacterMap *aCmap);
// add a cmap to the shared cmap set
gfxCharacterMap* AddCmap(const gfxCharacterMap *aCharMap);
// remove the cmap from the shared cmap set
void RemoveCmap(const gfxCharacterMap *aCharMap);
protected:
class MemoryReporter
: public nsIMemoryMultiReporter
@ -321,10 +264,6 @@ protected:
nsTHashtable<nsStringHashKey> mBadUnderlineFamilyNames;
// character map data shared across families
// contains weak ptrs to cmaps shared by font entry objects
nsTHashtable<CharMapHashKey> mSharedCmaps;
// data used as part of the font cmap loading process
nsTArray<nsRefPtr<gfxFontFamily> > mFontFamiliesToLoad;
PRUint32 mStartIndex;