app_server: keep pinned fonts accessible by ID after removal
On font removal styles may still be referenced by views, pictures or whatever else. In that case, what we were doing had the following effects: - The style is still available through the family. So it is still returned when listing fonts. - The style is not available by ID. So a few app server messages will fail, including those for string width or character escapements. Moreover, if the removal was due to an update, adding the style again fails because we already have one by that name. If all the old references are finally dropped, we end up without the old nor the updated style. We now do the opposite: until all references are dropped, a style can still be fetched by ID (that is, by an object that loaded it before being removed), but it is not listed anymore (so it won't be given to an app loading a font by name or by changing the style of a font of the same family). Fixes: #18868 Change-Id: Ia64744afeb9297fd446e437d08636733b6dc0aec Reviewed-on: https://review.haiku-os.org/c/haiku/+/7633 Reviewed-by: Fredrik Holmqvist <fredrik.holmqvist@gmail.com> Reviewed-by: Adrien Destugues <pulkomandy@pulkomandy.tk> Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org> Haiku-Format: Haiku-format Bot <no-reply+haikuformatbot@haiku-os.org> Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
31e7087b07
commit
0b8508801b
|
@ -2014,7 +2014,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||
// 1) font_family - name of font family to use
|
||||
// 2) font_style - name of style in family
|
||||
// 3) family ID - only used if 1) is empty
|
||||
// 4) style ID - only used if 2) is empty
|
||||
// 4) style ID - only used if 1) and 2) are empty
|
||||
// 5) face - the font's current face
|
||||
|
||||
// Returns:
|
||||
|
|
|
@ -135,8 +135,6 @@ FontFamily::RemoveStyle(FontStyle* style)
|
|||
if (!fStyles.RemoveItem(style))
|
||||
return false;
|
||||
|
||||
style->_SetFontFamily(NULL, -1);
|
||||
|
||||
// force a refresh if a request for font flags is needed
|
||||
fFlags = kInvalidFamilyFlags;
|
||||
return true;
|
||||
|
@ -239,20 +237,6 @@ FontFamily::GetStyle(const char *name) const
|
|||
}
|
||||
|
||||
|
||||
FontStyle*
|
||||
FontFamily::GetStyleByID(uint16 id) const
|
||||
{
|
||||
int32 count = fStyles.CountItems();
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
FontStyle* style = fStyles.ItemAt(i);
|
||||
if (style->ID() == id)
|
||||
return style;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
FontStyle*
|
||||
FontFamily::GetStyleMatchingFace(uint16 face) const
|
||||
{
|
||||
|
|
|
@ -35,7 +35,6 @@ public:
|
|||
|
||||
FontStyle* GetStyle(const char* style) const;
|
||||
FontStyle* GetStyleMatchingFace(uint16 face) const;
|
||||
FontStyle* GetStyleByID(uint16 face) const;
|
||||
|
||||
uint16 ID() const
|
||||
{ return fID; }
|
||||
|
|
|
@ -204,7 +204,11 @@ FontManager::GetStyle(uint16 familyID, uint16 styleID) const
|
|||
ASSERT(IsLocked());
|
||||
|
||||
FontKey key(familyID, styleID);
|
||||
return fStyleHashTable.Get(key);
|
||||
FontStyle* style = fStyleHashTable.Get(key);
|
||||
if (style != NULL)
|
||||
return style;
|
||||
|
||||
return fDelistedStyleHashTable.Get(key);
|
||||
}
|
||||
|
||||
|
||||
|
@ -214,7 +218,7 @@ FontManager::GetStyle(uint16 familyID, uint16 styleID) const
|
|||
\param family The font's family or NULL in which case \a familyID is used
|
||||
\param style The font's style or NULL in which case \a styleID is used
|
||||
\param familyID will only be used if \a family is NULL (or empty)
|
||||
\param styleID will only be used if \a style is NULL (or empty)
|
||||
\param styleID will only be used if \a family and \a style are NULL (or empty)
|
||||
\param face is used to specify the style if both \a style is NULL or empty
|
||||
and styleID is 0xffff.
|
||||
|
||||
|
@ -228,6 +232,11 @@ FontManager::GetStyle(const char* familyName, const char* styleName,
|
|||
|
||||
FontFamily* family;
|
||||
|
||||
if (styleID != 0xffff && (familyName == NULL || !familyName[0])
|
||||
&& (styleName == NULL || !styleName[0])) {
|
||||
return GetStyle(familyID, styleID);
|
||||
}
|
||||
|
||||
// find family
|
||||
|
||||
if (familyName != NULL && familyName[0])
|
||||
|
@ -243,9 +252,6 @@ FontManager::GetStyle(const char* familyName, const char* styleName,
|
|||
if (styleName != NULL && styleName[0])
|
||||
return family->GetStyle(styleName);
|
||||
|
||||
if (styleID != 0xffff)
|
||||
return family->GetStyleByID(styleID);
|
||||
|
||||
// try to get from face
|
||||
return family->GetStyleMatchingFace(face);
|
||||
}
|
||||
|
@ -283,15 +289,15 @@ FontManager::RemoveStyle(FontStyle* style)
|
|||
if (family == NULL)
|
||||
debugger("family is NULL!");
|
||||
|
||||
FontStyle* check = GetStyle(family->ID(), style->ID());
|
||||
if (check != NULL)
|
||||
debugger("style removed but still available!");
|
||||
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->RemoveStyle(style)
|
||||
&& family->CountStyles() == 0) {
|
||||
fFamilies.RemoveItem(family);
|
||||
if (family->CountStyles() == 0 && !fDelistedFamilies.ContainsKey(family))
|
||||
delete family;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -351,16 +357,37 @@ FontManager::_RemoveFont(uint16 familyID, uint16 styleID)
|
|||
{
|
||||
ASSERT(IsLocked());
|
||||
|
||||
return fStyleHashTable.Remove(FontKey(familyID, styleID));
|
||||
FontKey key(familyID, styleID);
|
||||
FontStyle* style = fStyleHashTable.Get(key);
|
||||
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);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FontManager::_RemoveAllFonts()
|
||||
{
|
||||
for (int32 i = fFamilies.CountItems(); i-- > 0;)
|
||||
delete fFamilies.RemoveItemAt(i);
|
||||
for (int32 i = fFamilies.CountItems(); i-- > 0;) {
|
||||
FontFamily* family = fFamilies.RemoveItemAt(i);
|
||||
fDelistedFamilies.Remove(family);
|
||||
delete family;
|
||||
}
|
||||
|
||||
HashMap<FontKey, FontStyle*>::Iterator it = fDelistedStyleHashTable.GetIterator();
|
||||
while (it.HasNext()) {
|
||||
FontFamily* family = it.Next().value->Family();
|
||||
fDelistedFamilies.Remove(family);
|
||||
delete family;
|
||||
}
|
||||
|
||||
fDelistedFamilies.Clear();
|
||||
fStyleHashTable.Clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,9 @@ protected:
|
|||
|
||||
private:
|
||||
struct FontKey {
|
||||
FontKey()
|
||||
: familyID(0xffff), styleID(0xffff) {}
|
||||
|
||||
FontKey(uint16 family, uint16 style)
|
||||
: familyID(family), styleID(style) {}
|
||||
|
||||
|
@ -99,8 +102,11 @@ private:
|
|||
private:
|
||||
typedef BObjectList<FontFamily> FamilyList;
|
||||
FamilyList fFamilies;
|
||||
HashMap<HashKeyPointer<FontFamily*>, int>
|
||||
fDelistedFamilies;
|
||||
|
||||
HashMap<FontKey, BReference<FontStyle> > fStyleHashTable;
|
||||
HashMap<FontKey, FontStyle*> fDelistedStyleHashTable;
|
||||
|
||||
uint16 fNextID;
|
||||
};
|
||||
|
|
|
@ -571,7 +571,7 @@ GlobalFontManager::GetStyle(uint16 familyID, uint16 styleID) const
|
|||
\param family The font's family or NULL in which case \a familyID is used
|
||||
\param style The font's style or NULL in which case \a styleID is used
|
||||
\param familyID will only be used if \a family is NULL (or empty)
|
||||
\param styleID will only be used if \a style is NULL (or empty)
|
||||
\param styleID will only be used if \a family and \a style are NULL (or empty)
|
||||
\param face is used to specify the style if both \a style is NULL or empty
|
||||
and styleID is 0xffff.
|
||||
|
||||
|
@ -585,6 +585,11 @@ GlobalFontManager::GetStyle(const char* familyName, const char* styleName,
|
|||
|
||||
FontFamily* family;
|
||||
|
||||
if (styleID != 0xffff && (familyName == NULL || !familyName[0])
|
||||
&& (styleName == NULL || !styleName[0])) {
|
||||
return GetStyle(familyID, styleID);
|
||||
}
|
||||
|
||||
// find family
|
||||
|
||||
if (familyName != NULL && familyName[0])
|
||||
|
@ -613,9 +618,6 @@ GlobalFontManager::GetStyle(const char* familyName, const char* styleName,
|
|||
return family->GetStyle(styleName);
|
||||
}
|
||||
|
||||
if (styleID != 0xffff)
|
||||
return family->GetStyleByID(styleID);
|
||||
|
||||
// try to get from face
|
||||
return family->GetStyleMatchingFace(face);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue