app_server: make FontFamily referenceable

FontStyle will be keeping the references, so the family will exist as
long as there's a style pointing to it.

Change-Id: I639f7914be924a84d5db5882c638a4dac665aa23
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7634
Reviewed-by: Fredrik Holmqvist <fredrik.holmqvist@gmail.com>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
Reviewed-by: Adrien Destugues <pulkomandy@pulkomandy.tk>
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
Máximo Castañeda 2024-04-18 20:36:54 +02:00 committed by waddlesplash
parent 0b8508801b
commit 7866929cf9
6 changed files with 29 additions and 57 deletions

View File

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

View File

@ -11,6 +11,7 @@
#include <ObjectList.h>
#include <Referenceable.h>
#include <String.h>
#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;

View File

@ -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<FontFamily> 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<FontKey, FontStyle*>::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<FontKey, FontStyle*>::Iterator delisted = fDelistedStyleHashTable.GetIterator();
while (delisted.HasNext())
delisted.Next().value->_SetFontFamily(NULL, -1);
fDelistedStyleHashTable.Clear();
HashMap<FontKey, BReference<FontStyle> >::Iterator referenced = fStyleHashTable.GetIterator();
while (referenced.HasNext())
referenced.Next().value->_SetFontFamily(NULL, -1);
fStyleHashTable.Clear();
}

View File

@ -102,8 +102,6 @@ private:
private:
typedef BObjectList<FontFamily> FamilyList;
FamilyList fFamilies;
HashMap<HashKeyPointer<FontFamily*>, int>
fDelistedFamilies;
HashMap<FontKey, BReference<FontStyle> > fStyleHashTable;
HashMap<FontKey, FontStyle*> fDelistedStyleHashTable;

View File

@ -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;
}

View File

@ -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<FontFamily>
fFamily;
uint16 fID;
BRect fBounds;