* Removing fonts now works as expected.

* removing a font family or style now always goes through the font manager.
* removed FreeType "cache" remains (it wasn't used, anyway, and won't be used
  by us).
* renamed SharedObject to ReferenceCounting as that's what it does.
* the default fonts weren't deleted on shutdown.
* added temporary work-around for waiting until a newly created entry is complete
  (just waits a moment...) - this will be fixed once Haiku supports this in a
  better way.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14833 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-11-10 17:32:35 +00:00
parent 779d5736a3
commit c12196d47b
6 changed files with 106 additions and 78 deletions
+3 -4
View File
@@ -19,7 +19,7 @@
#include <ft2build.h>
#include FT_FREETYPE_H
#include "SharedObject.h"
#include "ReferenceCounting.h"
#include "HashTable.h"
@@ -66,7 +66,7 @@ class FontKey : public Hashable {
FontStyle objects help abstract a lot of the font engine details while
still offering plenty of information the style in question.
*/
class FontStyle : public SharedObject, public Hashable, public BLocker {
class FontStyle : public ReferenceCounting, public Hashable, public BLocker {
public:
FontStyle(node_ref& nodeRef, const char* path, FT_Face face);
virtual ~FontStyle();
@@ -189,8 +189,7 @@ class FontFamily {
const char* Name() const;
bool AddStyle(FontStyle* style);
bool RemoveStyle(const char* style, bool deleteSelfIfEmpty = true);
bool RemoveStyle(FontStyle* style, bool deleteSelfIfEmpty = true);
bool RemoveStyle(FontStyle* style);
FontStyle* GetStyle(const char* style) const;
FontStyle* GetStyleMatchingFace(uint16 face) const;
+5 -2
View File
@@ -17,7 +17,6 @@
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_CACHE_H
class BPath;
@@ -56,6 +55,9 @@ class FontManager : public BLooper {
FontStyle *GetStyle(uint16 familyID, uint16 styleID) const;
FontStyle* FindStyleMatchingFace(uint16 face) const;
void RemoveStyle(FontStyle* style);
// this call must not be used by anything else than class FontStyle
const ServerFont* DefaultPlainFont() const;
const ServerFont* DefaultBoldFont() const;
const ServerFont* DefaultFixedFont() const;
@@ -78,8 +80,9 @@ class FontManager : public BLooper {
status_t _AddPath(const char* path);
status_t _AddPath(BEntry& entry, font_directory** _newDirectory = NULL);
void _RemoveStyle(font_directory& directory, FontStyle* style);
void _RemoveStyle(dev_t device, uint64 directory, uint64 node);
FontFamily* _FindFamily(const char* family) const;
void _RemoveFamily(const char* family);
void _ScanFontsIfNecessary();
void _ScanFonts();
@@ -6,26 +6,26 @@
* DarkWyrm <bpmagic@columbus.rr.com>
* Axel Dörfler, axeld@pinc-software.de
*/
#ifndef SHARED_OBJECT_H
#define SHARED_OBJECT_H
#ifndef REFERENCE_COUNTING_H
#define REFERENCE_COUNTING_H
#include <SupportDefs.h>
/*!
\class SharedObject SharedObject.h
\brief Base class for shared objects
SharedObjects track dependencies upon a particular object. In this way, is is
possible to ensure that a shared resource is not deleted if something else
\class ReferenceCounting ReferenceCounting.h
\brief Base class for reference counting objects
ReferenceCounting objects track dependencies upon a particular object. In this way,
it is possible to ensure that a shared resource is not deleted if something else
needs it. How the dependency tracking is done largely depends on the child class.
*/
class SharedObject {
class ReferenceCounting {
public:
SharedObject()
ReferenceCounting()
: fReferenceCount(1) {}
virtual ~SharedObject() {}
virtual ~ReferenceCounting() {}
inline void Acquire();
inline bool Release();
@@ -36,13 +36,13 @@ class SharedObject {
inline void
SharedObject::Acquire()
ReferenceCounting::Acquire()
{
atomic_add(&fReferenceCount, 1);
}
inline bool
SharedObject::Release()
ReferenceCounting::Release()
{
if (atomic_add(&fReferenceCount, -1) == 1) {
delete this;
@@ -52,4 +52,4 @@ SharedObject::Release()
return false;
}
#endif /* SHARED_OBJECT_H */
#endif /* REFERENCE_COUNTING_H */
+15 -30
View File
@@ -84,7 +84,7 @@ FontStyle::~FontStyle()
{
// make sure the font server is ours
if (fFamily != NULL && gFontManager->Lock()) {
fFamily->RemoveStyle(this, false);
gFontManager->RemoveStyle(this);
gFontManager->Unlock();
}
@@ -264,15 +264,19 @@ FontFamily::FontFamily(const char *name, uint16 id)
/*!
\brief Destructor
Deletes all child styles. Note that a FontFamily should not be deleted unless
its styles have no dependencies or some other really good reason, such as
system shutdown.
Deletes all attached styles. Note that a FontFamily must only be deleted
by the font manager.
*/
FontFamily::~FontFamily()
{
// styles are removing itself when deleted
for (int32 i = fStyles.CountItems(); i-- > 0;)
delete fStyles.ItemAt(i);
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);
delete style;
}
}
@@ -317,28 +321,13 @@ FontFamily::AddStyle(FontStyle *style)
}
bool
FontFamily::RemoveStyle(const char* styleName, bool deleteSelfIfEmpty)
{
FontStyle *style = GetStyle(styleName);
if (style != NULL)
return RemoveStyle(style, deleteSelfIfEmpty);
return false;
}
/*!
\brief Removes a style from the family.
The font family may be deleted during this call - the object might not
be valid anymore after this call.
The font style will not be altered.
\param style The style to be removed from the family
The font style will not be deleted.
*/
bool
FontFamily::RemoveStyle(FontStyle* style, bool deleteSelfIfEmpty)
FontFamily::RemoveStyle(FontStyle* style)
{
if (!gFontManager->IsLocked()) {
debugger("FontFamily::RemoveStyle() called without having the font manager locked!");
@@ -348,14 +337,10 @@ FontFamily::RemoveStyle(FontStyle* style, bool deleteSelfIfEmpty)
if (!fStyles.RemoveItem(style))
return false;
// force a refresh if a request for font flags is needed
fFlags = kInvalidFamilyFlags;
style->_SetFontFamily(NULL, -1);
if (deleteSelfIfEmpty && CountStyles() == 0)
delete this;
// force a refresh if a request for font flags is needed
fFlags = kInvalidFamilyFlags;
return true;
}
+69 -29
View File
@@ -38,7 +38,6 @@
// TODO: needs some more work for multi-user support
static FTC_Manager ftmanager;
FT_Library gFreeTypeLibrary;
FontManager *gFontManager = NULL;
@@ -116,29 +115,22 @@ FontManager::FontManager()
fInitStatus = _SetDefaultFonts();
}
/*
Fire up the font caching subsystem.
The three zeros tell FreeType to use the defaults, which are 2 faces,
4 face sizes, and a maximum of 200000 bytes. I will probably change
these numbers in the future to maximize performance for your "average"
application.
*/
// if (FTC_Manager_New(gFreeTypeLibrary, 0, 0, 0, &face_requester, NULL, &ftmanager) != 0)
// fInit = false;
}
//! Frees items allocated in the constructor and shuts down FreeType
FontManager::~FontManager()
{
delete fDefaultPlainFont;
delete fDefaultBoldFont;
delete fDefaultFixedFont;
// free families before we're done with FreeType
for (int32 i = fFamilies.CountItems(); i-- > 0;) {
delete fFamilies.ItemAt(i);
}
FTC_Manager_Done(ftmanager);
FT_Done_FreeType(gFreeTypeLibrary);
}
@@ -165,6 +157,10 @@ FontManager::MessageReceived(BMessage* message)
|| message->FindString("name", &name) != B_OK)
break;
// TODO: make this better (possible under Haiku)
snooze(100000);
// let the font be written completely before trying to open it
BEntry entry;
if (set_entry(nodeRef, name, entry) != B_OK)
break;
@@ -184,6 +180,7 @@ FontManager::MessageReceived(BMessage* message)
}
break;
}
case B_ENTRY_MOVED:
{
// has the entry been moved into a monitored directory or has
@@ -234,16 +231,20 @@ FontManager::MessageReceived(BMessage* message)
if (entry.GetNodeRef(&nodeRef) == B_OK
&& (directory = _FindDirectory(nodeRef)) != NULL)
_RemoveDirectory(directory);
} else
WTRACE(("font removed: %s\n", name));
} else {
// remove font style from directory
_RemoveStyle(nodeRef.device, fromNode, node);
}
}
break;
}
case B_ENTRY_REMOVED:
{
node_ref nodeRef;
uint64 directoryNode;
if (message->FindInt32("device", &nodeRef.device) != B_OK
|| message->FindInt64("directory", (int64 *)&directoryNode) != B_OK
|| message->FindInt64("node", &nodeRef.node) != B_OK)
break;
@@ -252,8 +253,8 @@ FontManager::MessageReceived(BMessage* message)
// the directory has been removed, so we remove it as well
_RemoveDirectory(directory);
} else {
// a font was removed?
WTRACE(("removed a font?"));
// remove font style from directory
_RemoveStyle(nodeRef.device, directoryNode, nodeRef.node);
}
break;
}
@@ -278,23 +279,40 @@ FontManager::_LoadRecentFontMappings()
/*!
\brief Removes a font family from the font list
\param family The family to remove
\brief Removes the style from the font directory.
It doesn't necessary delete the font style, if it's still
in use, though.
*/
void
FontManager::_RemoveFamily(const char *familyName)
FontManager::_RemoveStyle(font_directory& directory, FontStyle* style)
{
FontFamily *family = GetFamily(familyName);
if (family) {
// remove styles from hash
for (int32 i = 0; i < family->CountStyles(); i++) {
FontStyle* style = family->StyleAt(i);
WTRACE(("font removed: %s\n", style->Name()));
fStyleHashTable.RemoveItem(*style);
}
directory.styles.RemoveItem(style);
directory.revision++;
fFamilies.RemoveItem(family);
delete family;
fStyleHashTable.RemoveItem(*style);
style->Release();
}
void
FontManager::_RemoveStyle(dev_t device, uint64 directoryNode, uint64 node)
{
// remove font style from directory
node_ref nodeRef;
nodeRef.device = device;
nodeRef.node = directoryNode;
font_directory* directory = _FindDirectory(nodeRef);
if (directory != NULL) {
// find style in directory and remove it
nodeRef.node = node;
FontStyle* style = directory->FindStyle(nodeRef);
if (style != NULL)
_RemoveStyle(*directory, style);
}
}
@@ -863,6 +881,28 @@ FontManager::FindStyleMatchingFace(uint16 face) const
}
/*!
\brief This call is used by the FontStyle class - and the FontStyle class
only - to remove itself from the font manager.
At this point, the style is already no longer available to the user.
*/
void
FontManager::RemoveStyle(FontStyle* style)
{
FontFamily* family = style->Family();
if (family == NULL)
debugger("family is NULL!");
FontStyle* check = GetStyle(family->ID(), style->ID());
if (check != NULL)
debugger("style removed but still available!");
if (family->RemoveStyle(style)
&& family->CountStyles() == 0)
fFamilies.RemoveItem(family);
}
const ServerFont*
FontManager::DefaultPlainFont() const
{
+1
View File
@@ -19,6 +19,7 @@
#include "truncate_string.h"
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_OUTLINE_H
#include "ServerFont.h"