* 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:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
+13
-13
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "truncate_string.h"
|
||||
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_GLYPH_H
|
||||
#include FT_OUTLINE_H
|
||||
|
||||
#include "ServerFont.h"
|
||||
|
||||
Reference in New Issue
Block a user