diff --git a/src/servers/app/font/FontFamily.cpp b/src/servers/app/font/FontFamily.cpp index 88ba380f43..e03295f4ef 100644 --- a/src/servers/app/font/FontFamily.cpp +++ b/src/servers/app/font/FontFamily.cpp @@ -62,24 +62,6 @@ FontFamily::FontFamily(const char *name, uint16 id) } -/*! - \brief Destructor - - Deletes all attached styles. Note that a FontFamily must only be deleted - by the font manager. -*/ -FontFamily::~FontFamily() -{ - for (int32 i = fStyles.CountItems(); i-- > 0;) { - FontStyle* style = fStyles.RemoveItemAt(i); - - // we remove us before deleting the style, so that the font manager - // is not contacted to remove the style from us - style->_SetFontFamily(NULL, -1); - } -} - - /*! \brief Returns the name of the family \return The family's name diff --git a/src/servers/app/font/FontFamily.h b/src/servers/app/font/FontFamily.h index e75faca607..b66e4ece93 100644 --- a/src/servers/app/font/FontFamily.h +++ b/src/servers/app/font/FontFamily.h @@ -11,6 +11,7 @@ #include +#include #include #include "FontStyle.h" @@ -23,10 +24,9 @@ FontFamily objects bring together many styles of the same face, such as Arial Roman, Arial Italic, Arial Bold, etc. */ -class FontFamily { +class FontFamily : public BReferenceable { public: FontFamily(const char* name, uint16 id); - virtual ~FontFamily(); const char* Name() const; diff --git a/src/servers/app/font/FontManager.cpp b/src/servers/app/font/FontManager.cpp index 2929e47248..ab186dca9e 100644 --- a/src/servers/app/font/FontManager.cpp +++ b/src/servers/app/font/FontManager.cpp @@ -289,15 +289,8 @@ FontManager::RemoveStyle(FontStyle* style) if (family == NULL) debugger("family is NULL!"); + family->RemoveStyle(style); fDelistedStyleHashTable.Remove(FontKey(family->ID(), style->ID())); - int count = fDelistedFamilies.Get(family) - 1; - if (count == 0) - fDelistedFamilies.Remove(family); - else if (count > 0) - fDelistedFamilies.Put(family, count); - - if (family->CountStyles() == 0 && !fDelistedFamilies.ContainsKey(family)) - delete family; } @@ -307,22 +300,20 @@ FontManager::_AddFont(FT_Face face, node_ref nodeRef, const char* path, { ASSERT(IsLocked()); - FontFamily* family = _FindFamily(face->family_name); - bool isNewFontFamily = family == NULL; + BReference family(_FindFamily(face->family_name)); + bool isNewFontFamily = !family.IsSet(); - if (family != NULL && family->HasStyle(face->style_name)) { + if (family.IsSet() && family->HasStyle(face->style_name)) { // prevent adding the same style twice // (this indicates a problem with the installed fonts maybe?) FT_Done_Face(face); return B_NAME_IN_USE; } - if (family == NULL) { - family = new (std::nothrow) FontFamily(face->family_name, _NextID()); + if (!family.IsSet()) { + family.SetTo(new (std::nothrow) FontFamily(face->family_name, _NextID()), true); - if (family == NULL - || !fFamilies.BinaryInsert(family, compare_font_families)) { - delete family; + if (!family.IsSet() || !fFamilies.BinaryInsert(family, compare_font_families)) { FT_Done_Face(face); return B_NO_MEMORY; } @@ -335,10 +326,8 @@ FontManager::_AddFont(FT_Face face, node_ref nodeRef, const char* path, if (style == NULL || !family->AddStyle(style)) { delete style; - if (isNewFontFamily) { + if (isNewFontFamily) fFamilies.RemoveItem(family); - delete family; - } return B_NO_MEMORY; } @@ -362,7 +351,6 @@ FontManager::_RemoveFont(uint16 familyID, uint16 styleID) if (style != NULL) { fDelistedStyleHashTable.Put(key, style); FontFamily* family = style->Family(); - fDelistedFamilies.Put(family, fDelistedFamilies.Get(family) + 1); if (family->RemoveStyle(style) && family->CountStyles() == 0) fFamilies.RemoveItem(family); fStyleHashTable.Remove(key); @@ -374,20 +362,19 @@ FontManager::_RemoveFont(uint16 familyID, uint16 styleID) void FontManager::_RemoveAllFonts() { - for (int32 i = fFamilies.CountItems(); i-- > 0;) { - FontFamily* family = fFamilies.RemoveItemAt(i); - fDelistedFamilies.Remove(family); - delete family; - } + fFamilies.MakeEmpty(); - HashMap::Iterator it = fDelistedStyleHashTable.GetIterator(); - while (it.HasNext()) { - FontFamily* family = it.Next().value->Family(); - fDelistedFamilies.Remove(family); - delete family; - } + // Disconnect the styles from their families before removing them; once we + // get to this point, we are in the dtor and don't want them to call back. - fDelistedFamilies.Clear(); + HashMap::Iterator delisted = fDelistedStyleHashTable.GetIterator(); + while (delisted.HasNext()) + delisted.Next().value->_SetFontFamily(NULL, -1); + fDelistedStyleHashTable.Clear(); + + HashMap >::Iterator referenced = fStyleHashTable.GetIterator(); + while (referenced.HasNext()) + referenced.Next().value->_SetFontFamily(NULL, -1); fStyleHashTable.Clear(); } diff --git a/src/servers/app/font/FontManager.h b/src/servers/app/font/FontManager.h index 8e2f0e5efe..fcc56322bf 100644 --- a/src/servers/app/font/FontManager.h +++ b/src/servers/app/font/FontManager.h @@ -102,8 +102,6 @@ private: private: typedef BObjectList FamilyList; FamilyList fFamilies; - HashMap, int> - fDelistedFamilies; HashMap > fStyleHashTable; HashMap fDelistedStyleHashTable; diff --git a/src/servers/app/font/FontStyle.cpp b/src/servers/app/font/FontStyle.cpp index a97905293d..3d1c5446d7 100644 --- a/src/servers/app/font/FontStyle.cpp +++ b/src/servers/app/font/FontStyle.cpp @@ -96,7 +96,7 @@ FontStyle::FontStyle(node_ref& nodeRef, const char* path, FT_Face face, FontStyle::~FontStyle() { // make sure the font server is ours - if (fFamily != NULL && fFontManager->Lock()) { + if (fFamily.IsSet() && fFontManager->Lock()) { fFontManager->RemoveStyle(this); fFontManager->Unlock(); } @@ -227,7 +227,10 @@ FontStyle::UpdateFace(FT_Face face) void FontStyle::_SetFontFamily(FontFamily* family, uint16 id) { - fFamily = family; + if (fFamily.IsSet()) + fFamily->RemoveStyle(this); + + fFamily.SetTo(family); fID = id; } diff --git a/src/servers/app/font/FontStyle.h b/src/servers/app/font/FontStyle.h index 5a0850ab44..552648e4ed 100644 --- a/src/servers/app/font/FontStyle.h +++ b/src/servers/app/font/FontStyle.h @@ -144,6 +144,7 @@ class FontStyle : public BReferenceable { private: friend class FontFamily; + friend class FontManager; uint16 _TranslateStyleToFace(const char *name) const; void _SetFontFamily(FontFamily* family, uint16 id); private: @@ -152,7 +153,8 @@ class FontStyle : public BReferenceable { BPath fPath; node_ref fNodeRef; - FontFamily* fFamily; + BReference + fFamily; uint16 fID; BRect fBounds;