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:
jshin%mailaps.org 2003-12-10 21:27:01 +00:00
Родитель 29a24bcffe
Коммит 293ef3fbfe
2 изменённых файлов: 55 добавлений и 99 удалений

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

@ -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__