зеркало из https://github.com/mozilla/pjs.git
bug 226623: XFT build crashes on PLHashRawAdd. Switch to nsClassHashTable and add a new HashKeyType that duplicates a string in ctor. (r=bsmedberg, sr=bryner, a1.6=tor)
This commit is contained in:
Родитель
29a24bcffe
Коммит
293ef3fbfe
|
@ -61,7 +61,7 @@
|
|||
#include "nsIPersistentProperties2.h"
|
||||
#include "nsCompressedCharMap.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "plhash.h"
|
||||
#include "nsClassHashtable.h"
|
||||
|
||||
#include <gdk/gdkx.h>
|
||||
#include <freetype/tttables.h>
|
||||
|
@ -168,7 +168,7 @@ enum nsXftFontType {
|
|||
|
||||
// a class to hold some essential information about font.
|
||||
// it's shared and cached with 'family name' as hash key.
|
||||
class nsFontXftInfo : public PLHashEntry {
|
||||
class nsFontXftInfo {
|
||||
public:
|
||||
nsFontXftInfo() : mCCMap(nsnull), mConverter(0),
|
||||
mFontType(eFontTypeUnicode)
|
||||
|
@ -190,20 +190,6 @@ class nsFontXftInfo : public PLHashEntry {
|
|||
FT_Encoding mFT_Encoding;
|
||||
};
|
||||
|
||||
PR_STATIC_CALLBACK(void*) fontmapAllocTable(void *pool, size_t size);
|
||||
PR_STATIC_CALLBACK(void) fontmapFreeTable (void *pool, void *item);
|
||||
PR_STATIC_CALLBACK(PLHashEntry*) fontmapAllocEntry(void *pool,
|
||||
const void *key);
|
||||
PR_STATIC_CALLBACK(void) fontmapFreeEntry (void *pool,
|
||||
PLHashEntry *he,
|
||||
PRUint32 flag);
|
||||
|
||||
PLHashAllocOps fontmapHashAllocOps = {
|
||||
fontmapAllocTable, fontmapFreeTable,
|
||||
fontmapAllocEntry, fontmapFreeEntry
|
||||
};
|
||||
|
||||
|
||||
struct MozXftLangGroup {
|
||||
const char *mozLangGroup;
|
||||
FcChar32 character;
|
||||
|
@ -367,7 +353,10 @@ static NS_DEFINE_CID(kCharsetConverterManagerCID,
|
|||
static PRBool gInitialized = PR_FALSE;
|
||||
static nsIPersistentProperties* gFontEncodingProperties = nsnull;
|
||||
static nsICharsetConverterManager* gCharsetManager = nsnull;
|
||||
static PLHashTable* gFontXftMaps = nsnull;
|
||||
|
||||
typedef nsClassHashtable<nsCharPtrHashKey, nsFontXftInfo> nsFontXftInfoHash;
|
||||
static nsFontXftInfoHash gFontXftMaps;
|
||||
#define INITIAL_FONT_MAP_SIZE 32
|
||||
|
||||
static nsresult GetEncoding(const char* aFontName,
|
||||
char **aEncoding,
|
||||
|
@ -378,9 +367,6 @@ static nsresult GetConverter(const char* aEncoding,
|
|||
static nsresult FreeGlobals(void);
|
||||
static nsFontXftInfo* GetFontXftInfo(FcPattern* aPattern);
|
||||
|
||||
static PLHashNumber HashKey(const void* aString);
|
||||
static PRIntn CompareKeys(const void* aStr1, const void* aStr2);
|
||||
|
||||
nsFontMetricsXft::nsFontMetricsXft(): mMiniFont(nsnull)
|
||||
{
|
||||
if (!gXftFontLoad)
|
||||
|
@ -513,11 +499,9 @@ nsFontMetricsXft::Init(const nsFont& aFont, nsIAtom* aLangGroup,
|
|||
FreeGlobals();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!gFontXftMaps) {
|
||||
gFontXftMaps = PL_NewHashTable(0, HashKey, CompareKeys, nsnull,
|
||||
&fontmapHashAllocOps, nsnull);
|
||||
}
|
||||
if (!gFontXftMaps) { // error checking
|
||||
|
||||
if (!gFontXftMaps.IsInitialized() &&
|
||||
!gFontXftMaps.Init(INITIAL_FONT_MAP_SIZE)) {
|
||||
FreeGlobals();
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -1267,8 +1251,9 @@ nsFontMetricsXft::DoMatch(PRBool aMatchAll)
|
|||
}
|
||||
|
||||
// Create a list of new font objects based on the fonts returned
|
||||
// as part of the query
|
||||
for (int i=0; i < set->nfont; ++i) {
|
||||
// as part of the query. We start at mLoadedFonts.Count() so as to
|
||||
// not re-add the best match font we've already loaded.
|
||||
for (int i=mLoadedFonts.Count(); i < set->nfont; ++i) {
|
||||
if (PR_LOG_TEST(gXftFontLoad, PR_LOG_DEBUG)) {
|
||||
char *name;
|
||||
FcPatternGetString(set->fonts[i], FC_FAMILY, 0, (FcChar8 **)&name);
|
||||
|
@ -2290,37 +2275,6 @@ nsFontXftCustom::SetFT_FaceCharmap(void)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Hash table allocation for gFontXftMaps made up of
|
||||
// (family, nsFontXftInfo) pairs. Copied from nsFontMetricsWin.cpp.
|
||||
// XXX : jshin I'd love to use brand-new nsClassHashtable, but I can't
|
||||
// get it compiled with g++ 3.2 under Linux.
|
||||
PR_STATIC_CALLBACK(void*) fontmapAllocTable(void *pool, size_t size)
|
||||
{
|
||||
return nsMemory::Alloc(size);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(void) fontmapFreeTable(void *pool, void *item)
|
||||
{
|
||||
nsMemory::Free(item);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(PLHashEntry*) fontmapAllocEntry(void *pool, const void *key)
|
||||
{
|
||||
return new nsFontXftInfo();
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(void) fontmapFreeEntry(void *pool, PLHashEntry *he,
|
||||
PRUint32 flag)
|
||||
{
|
||||
// we don't have to free 'key' because key is from FcPatternGet()
|
||||
// that owns it.
|
||||
if (flag == HT_FREE_ENTRY) {
|
||||
nsFontXftInfo *fontInfo = NS_STATIC_CAST(nsFontXftInfo *, he);
|
||||
if (fontInfo)
|
||||
delete fontInfo;
|
||||
}
|
||||
}
|
||||
|
||||
// class nsAutoBuffer
|
||||
|
||||
nsAutoBuffer::nsAutoBuffer()
|
||||
|
@ -2968,10 +2922,7 @@ FreeGlobals(void)
|
|||
NS_IF_RELEASE(gFontEncodingProperties);
|
||||
NS_IF_RELEASE(gCharsetManager);
|
||||
|
||||
if (gFontXftMaps) {
|
||||
PL_HashTableDestroy(gFontXftMaps);
|
||||
gFontXftMaps = nsnull;
|
||||
}
|
||||
gFontXftMaps.Clear();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2987,25 +2938,19 @@ GetFontXftInfo(FcPattern* aPattern)
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
NS_ASSERTION(gFontXftMaps, "gFontXMaps should not be null by now.");
|
||||
NS_ASSERTION(gFontXftMaps.IsInitialized(), "gFontXMaps should be init'd by now.");
|
||||
|
||||
// shouldn't be NULL, using it as a flag to catch bad changes
|
||||
PLHashEntry *he, **hep = nsnull;
|
||||
PLHashNumber hash;
|
||||
nsFontXftInfo* info;
|
||||
|
||||
hash = HashKey(family);
|
||||
hep = PL_HashTableRawLookup(gFontXftMaps, hash, family);
|
||||
he = *hep;
|
||||
if (he) {
|
||||
// cached entry found.
|
||||
return (NS_STATIC_CAST(nsFontXftInfo *, he));
|
||||
}
|
||||
// cached entry found.
|
||||
if (gFontXftMaps.Get(family, &info))
|
||||
return info;
|
||||
|
||||
PRUint16* ccmap = nsnull;
|
||||
nsCOMPtr<nsIUnicodeEncoder> converter;
|
||||
nsXftFontType fontType = eFontTypeUnicode;
|
||||
nsXPIDLCString encoding;
|
||||
FT_Encoding ftEncoding = ft_encoding_unicode;
|
||||
PRUint16* ccmap = nsnull;
|
||||
|
||||
// See if a font has a custom/private encoding by matching
|
||||
// its family name against the list in fontEncoding.properties
|
||||
|
@ -3028,24 +2973,18 @@ GetFontXftInfo(FcPattern* aPattern)
|
|||
|
||||
// XXX Need to check if an identical map has already been added - Bug 75260
|
||||
// For Xft, this doesn't look as critical as in GFX Win.
|
||||
NS_ASSERTION(hep, "bad code");
|
||||
|
||||
nsFontXftInfo* info;
|
||||
info = new nsFontXftInfo;
|
||||
if (!info)
|
||||
return nsnull;
|
||||
|
||||
// Put (family, info) pair to hash. family returned by FcPatternGet()
|
||||
// is just a reference so that we shouldn't free it.
|
||||
he = PL_HashTableRawAdd(gFontXftMaps, hep, hash, family, nsnull);
|
||||
if (!he)
|
||||
return nsnull;
|
||||
|
||||
info = NS_STATIC_CAST(nsFontXftInfo*, he);
|
||||
he->value = info;
|
||||
// will be freed by ~nsFontXftInfo() invoked by fontmapFreeEntry
|
||||
info->mCCMap = ccmap;
|
||||
info->mConverter = converter;
|
||||
info->mFontType = fontType;
|
||||
info->mFT_Encoding = ftEncoding;
|
||||
|
||||
gFontXftMaps.Put(family, info);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
@ -3121,17 +3060,3 @@ ConvertUCS4ToCustom(FcChar32 *aSrc, PRUint32 aSrcLen,
|
|||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* static */
|
||||
PLHashNumber
|
||||
HashKey(const void* aString)
|
||||
{
|
||||
return PLHashNumber(nsCRT::HashCode((const char *) aString));
|
||||
}
|
||||
|
||||
/* static */
|
||||
PRIntn
|
||||
CompareKeys(const void* aStr1, const void* aStr2)
|
||||
{
|
||||
return nsCRT::strcmp((const char *) aStr1, (const char *) aStr2) == 0;
|
||||
}
|
||||
|
|
|
@ -247,4 +247,35 @@ private:
|
|||
const char* mKey;
|
||||
};
|
||||
|
||||
/**
|
||||
* hashkey wrapper for const char*; at construction, this class duplicates
|
||||
* a string pointed to by the pointer so that it doesn't matter whether or not
|
||||
* the string lives longer than the hash table.
|
||||
*/
|
||||
class NS_COM nsCharPtrHashKey : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
typedef const char* KeyType;
|
||||
typedef const char* KeyTypePointer;
|
||||
|
||||
nsCharPtrHashKey(const char* aKey) : mKey(strdup(aKey)) { }
|
||||
nsCharPtrHashKey(const nsCharPtrHashKey& toCopy) : mKey(strdup(toCopy.mKey)) { }
|
||||
~nsCharPtrHashKey() { if (mKey) free(NS_CONST_CAST(char *, mKey)); }
|
||||
|
||||
const char* GetKey() const { return mKey; }
|
||||
const char* GetKeyPointer() const { return mKey; }
|
||||
PRBool KeyEquals(KeyTypePointer aKey) const
|
||||
{
|
||||
return !strcmp(mKey, aKey);
|
||||
}
|
||||
|
||||
static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
|
||||
static PLDHashNumber HashKey(KeyTypePointer aKey) { return nsCRT::HashCode(aKey); }
|
||||
|
||||
enum { ALLOW_MEMMOVE = PR_TRUE };
|
||||
|
||||
private:
|
||||
const char* mKey;
|
||||
};
|
||||
|
||||
#endif // nsTHashKeys_h__
|
||||
|
|
Загрузка…
Ссылка в новой задаче