* 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 <ft2build.h>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
#include "SharedObject.h"
|
#include "ReferenceCounting.h"
|
||||||
#include "HashTable.h"
|
#include "HashTable.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ class FontKey : public Hashable {
|
|||||||
FontStyle objects help abstract a lot of the font engine details while
|
FontStyle objects help abstract a lot of the font engine details while
|
||||||
still offering plenty of information the style in question.
|
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:
|
public:
|
||||||
FontStyle(node_ref& nodeRef, const char* path, FT_Face face);
|
FontStyle(node_ref& nodeRef, const char* path, FT_Face face);
|
||||||
virtual ~FontStyle();
|
virtual ~FontStyle();
|
||||||
@@ -189,8 +189,7 @@ class FontFamily {
|
|||||||
const char* Name() const;
|
const char* Name() const;
|
||||||
|
|
||||||
bool AddStyle(FontStyle* style);
|
bool AddStyle(FontStyle* style);
|
||||||
bool RemoveStyle(const char* style, bool deleteSelfIfEmpty = true);
|
bool RemoveStyle(FontStyle* style);
|
||||||
bool RemoveStyle(FontStyle* style, bool deleteSelfIfEmpty = true);
|
|
||||||
|
|
||||||
FontStyle* GetStyle(const char* style) const;
|
FontStyle* GetStyle(const char* style) const;
|
||||||
FontStyle* GetStyleMatchingFace(uint16 face) const;
|
FontStyle* GetStyleMatchingFace(uint16 face) const;
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
#include FT_CACHE_H
|
|
||||||
|
|
||||||
class BPath;
|
class BPath;
|
||||||
|
|
||||||
@@ -56,6 +55,9 @@ class FontManager : public BLooper {
|
|||||||
FontStyle *GetStyle(uint16 familyID, uint16 styleID) const;
|
FontStyle *GetStyle(uint16 familyID, uint16 styleID) const;
|
||||||
FontStyle* FindStyleMatchingFace(uint16 face) 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* DefaultPlainFont() const;
|
||||||
const ServerFont* DefaultBoldFont() const;
|
const ServerFont* DefaultBoldFont() const;
|
||||||
const ServerFont* DefaultFixedFont() const;
|
const ServerFont* DefaultFixedFont() const;
|
||||||
@@ -78,8 +80,9 @@ class FontManager : public BLooper {
|
|||||||
status_t _AddPath(const char* path);
|
status_t _AddPath(const char* path);
|
||||||
status_t _AddPath(BEntry& entry, font_directory** _newDirectory = NULL);
|
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;
|
FontFamily* _FindFamily(const char* family) const;
|
||||||
void _RemoveFamily(const char* family);
|
|
||||||
|
|
||||||
void _ScanFontsIfNecessary();
|
void _ScanFontsIfNecessary();
|
||||||
void _ScanFonts();
|
void _ScanFonts();
|
||||||
|
|||||||
+13
-13
@@ -6,26 +6,26 @@
|
|||||||
* DarkWyrm <bpmagic@columbus.rr.com>
|
* DarkWyrm <bpmagic@columbus.rr.com>
|
||||||
* Axel Dörfler, axeld@pinc-software.de
|
* Axel Dörfler, axeld@pinc-software.de
|
||||||
*/
|
*/
|
||||||
#ifndef SHARED_OBJECT_H
|
#ifndef REFERENCE_COUNTING_H
|
||||||
#define SHARED_OBJECT_H
|
#define REFERENCE_COUNTING_H
|
||||||
|
|
||||||
|
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class SharedObject SharedObject.h
|
\class ReferenceCounting ReferenceCounting.h
|
||||||
\brief Base class for shared objects
|
\brief Base class for reference counting objects
|
||||||
|
|
||||||
SharedObjects track dependencies upon a particular object. In this way, is is
|
ReferenceCounting objects track dependencies upon a particular object. In this way,
|
||||||
possible to ensure that a shared resource is not deleted if something else
|
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.
|
needs it. How the dependency tracking is done largely depends on the child class.
|
||||||
*/
|
*/
|
||||||
class SharedObject {
|
class ReferenceCounting {
|
||||||
public:
|
public:
|
||||||
SharedObject()
|
ReferenceCounting()
|
||||||
: fReferenceCount(1) {}
|
: fReferenceCount(1) {}
|
||||||
virtual ~SharedObject() {}
|
virtual ~ReferenceCounting() {}
|
||||||
|
|
||||||
inline void Acquire();
|
inline void Acquire();
|
||||||
inline bool Release();
|
inline bool Release();
|
||||||
@@ -36,13 +36,13 @@ class SharedObject {
|
|||||||
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
SharedObject::Acquire()
|
ReferenceCounting::Acquire()
|
||||||
{
|
{
|
||||||
atomic_add(&fReferenceCount, 1);
|
atomic_add(&fReferenceCount, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
SharedObject::Release()
|
ReferenceCounting::Release()
|
||||||
{
|
{
|
||||||
if (atomic_add(&fReferenceCount, -1) == 1) {
|
if (atomic_add(&fReferenceCount, -1) == 1) {
|
||||||
delete this;
|
delete this;
|
||||||
@@ -52,4 +52,4 @@ SharedObject::Release()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SHARED_OBJECT_H */
|
#endif /* REFERENCE_COUNTING_H */
|
||||||
@@ -84,7 +84,7 @@ FontStyle::~FontStyle()
|
|||||||
{
|
{
|
||||||
// make sure the font server is ours
|
// make sure the font server is ours
|
||||||
if (fFamily != NULL && gFontManager->Lock()) {
|
if (fFamily != NULL && gFontManager->Lock()) {
|
||||||
fFamily->RemoveStyle(this, false);
|
gFontManager->RemoveStyle(this);
|
||||||
gFontManager->Unlock();
|
gFontManager->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,15 +264,19 @@ FontFamily::FontFamily(const char *name, uint16 id)
|
|||||||
/*!
|
/*!
|
||||||
\brief Destructor
|
\brief Destructor
|
||||||
|
|
||||||
Deletes all child styles. Note that a FontFamily should not be deleted unless
|
Deletes all attached styles. Note that a FontFamily must only be deleted
|
||||||
its styles have no dependencies or some other really good reason, such as
|
by the font manager.
|
||||||
system shutdown.
|
|
||||||
*/
|
*/
|
||||||
FontFamily::~FontFamily()
|
FontFamily::~FontFamily()
|
||||||
{
|
{
|
||||||
// styles are removing itself when deleted
|
for (int32 i = fStyles.CountItems(); i-- > 0;) {
|
||||||
for (int32 i = fStyles.CountItems(); i-- > 0;)
|
FontStyle* style = fStyles.RemoveItemAt(i);
|
||||||
delete fStyles.ItemAt(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.
|
\brief Removes a style from the family.
|
||||||
|
|
||||||
The font family may be deleted during this call - the object might not
|
The font style will not be deleted.
|
||||||
be valid anymore after this call.
|
|
||||||
The font style will not be altered.
|
|
||||||
|
|
||||||
\param style The style to be removed from the family
|
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
FontFamily::RemoveStyle(FontStyle* style, bool deleteSelfIfEmpty)
|
FontFamily::RemoveStyle(FontStyle* style)
|
||||||
{
|
{
|
||||||
if (!gFontManager->IsLocked()) {
|
if (!gFontManager->IsLocked()) {
|
||||||
debugger("FontFamily::RemoveStyle() called without having the font manager locked!");
|
debugger("FontFamily::RemoveStyle() called without having the font manager locked!");
|
||||||
@@ -348,14 +337,10 @@ FontFamily::RemoveStyle(FontStyle* style, bool deleteSelfIfEmpty)
|
|||||||
if (!fStyles.RemoveItem(style))
|
if (!fStyles.RemoveItem(style))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// force a refresh if a request for font flags is needed
|
|
||||||
fFlags = kInvalidFamilyFlags;
|
|
||||||
|
|
||||||
style->_SetFontFamily(NULL, -1);
|
style->_SetFontFamily(NULL, -1);
|
||||||
|
|
||||||
if (deleteSelfIfEmpty && CountStyles() == 0)
|
// force a refresh if a request for font flags is needed
|
||||||
delete this;
|
fFlags = kInvalidFamilyFlags;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,6 @@
|
|||||||
|
|
||||||
// TODO: needs some more work for multi-user support
|
// TODO: needs some more work for multi-user support
|
||||||
|
|
||||||
static FTC_Manager ftmanager;
|
|
||||||
FT_Library gFreeTypeLibrary;
|
FT_Library gFreeTypeLibrary;
|
||||||
FontManager *gFontManager = NULL;
|
FontManager *gFontManager = NULL;
|
||||||
|
|
||||||
@@ -116,29 +115,22 @@ FontManager::FontManager()
|
|||||||
|
|
||||||
fInitStatus = _SetDefaultFonts();
|
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
|
//! Frees items allocated in the constructor and shuts down FreeType
|
||||||
FontManager::~FontManager()
|
FontManager::~FontManager()
|
||||||
{
|
{
|
||||||
|
delete fDefaultPlainFont;
|
||||||
|
delete fDefaultBoldFont;
|
||||||
|
delete fDefaultFixedFont;
|
||||||
|
|
||||||
// free families before we're done with FreeType
|
// free families before we're done with FreeType
|
||||||
|
|
||||||
for (int32 i = fFamilies.CountItems(); i-- > 0;) {
|
for (int32 i = fFamilies.CountItems(); i-- > 0;) {
|
||||||
delete fFamilies.ItemAt(i);
|
delete fFamilies.ItemAt(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
FTC_Manager_Done(ftmanager);
|
|
||||||
FT_Done_FreeType(gFreeTypeLibrary);
|
FT_Done_FreeType(gFreeTypeLibrary);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,6 +157,10 @@ FontManager::MessageReceived(BMessage* message)
|
|||||||
|| message->FindString("name", &name) != B_OK)
|
|| message->FindString("name", &name) != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// TODO: make this better (possible under Haiku)
|
||||||
|
snooze(100000);
|
||||||
|
// let the font be written completely before trying to open it
|
||||||
|
|
||||||
BEntry entry;
|
BEntry entry;
|
||||||
if (set_entry(nodeRef, name, entry) != B_OK)
|
if (set_entry(nodeRef, name, entry) != B_OK)
|
||||||
break;
|
break;
|
||||||
@@ -184,6 +180,7 @@ FontManager::MessageReceived(BMessage* message)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case B_ENTRY_MOVED:
|
case B_ENTRY_MOVED:
|
||||||
{
|
{
|
||||||
// has the entry been moved into a monitored directory or has
|
// 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
|
if (entry.GetNodeRef(&nodeRef) == B_OK
|
||||||
&& (directory = _FindDirectory(nodeRef)) != NULL)
|
&& (directory = _FindDirectory(nodeRef)) != NULL)
|
||||||
_RemoveDirectory(directory);
|
_RemoveDirectory(directory);
|
||||||
} else
|
} else {
|
||||||
WTRACE(("font removed: %s\n", name));
|
// remove font style from directory
|
||||||
|
_RemoveStyle(nodeRef.device, fromNode, node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case B_ENTRY_REMOVED:
|
case B_ENTRY_REMOVED:
|
||||||
{
|
{
|
||||||
node_ref nodeRef;
|
node_ref nodeRef;
|
||||||
|
uint64 directoryNode;
|
||||||
if (message->FindInt32("device", &nodeRef.device) != B_OK
|
if (message->FindInt32("device", &nodeRef.device) != B_OK
|
||||||
|
|| message->FindInt64("directory", (int64 *)&directoryNode) != B_OK
|
||||||
|| message->FindInt64("node", &nodeRef.node) != B_OK)
|
|| message->FindInt64("node", &nodeRef.node) != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -252,8 +253,8 @@ FontManager::MessageReceived(BMessage* message)
|
|||||||
// the directory has been removed, so we remove it as well
|
// the directory has been removed, so we remove it as well
|
||||||
_RemoveDirectory(directory);
|
_RemoveDirectory(directory);
|
||||||
} else {
|
} else {
|
||||||
// a font was removed?
|
// remove font style from directory
|
||||||
WTRACE(("removed a font?"));
|
_RemoveStyle(nodeRef.device, directoryNode, nodeRef.node);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -278,23 +279,40 @@ FontManager::_LoadRecentFontMappings()
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Removes a font family from the font list
|
\brief Removes the style from the font directory.
|
||||||
\param family The family to remove
|
|
||||||
|
It doesn't necessary delete the font style, if it's still
|
||||||
|
in use, though.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
FontManager::_RemoveFamily(const char *familyName)
|
FontManager::_RemoveStyle(font_directory& directory, FontStyle* style)
|
||||||
{
|
{
|
||||||
FontFamily *family = GetFamily(familyName);
|
WTRACE(("font removed: %s\n", style->Name()));
|
||||||
if (family) {
|
|
||||||
// remove styles from hash
|
|
||||||
for (int32 i = 0; i < family->CountStyles(); i++) {
|
|
||||||
FontStyle* style = family->StyleAt(i);
|
|
||||||
|
|
||||||
fStyleHashTable.RemoveItem(*style);
|
directory.styles.RemoveItem(style);
|
||||||
}
|
directory.revision++;
|
||||||
|
|
||||||
fFamilies.RemoveItem(family);
|
fStyleHashTable.RemoveItem(*style);
|
||||||
delete family;
|
|
||||||
|
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*
|
const ServerFont*
|
||||||
FontManager::DefaultPlainFont() const
|
FontManager::DefaultPlainFont() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "truncate_string.h"
|
#include "truncate_string.h"
|
||||||
|
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_GLYPH_H
|
||||||
#include FT_OUTLINE_H
|
#include FT_OUTLINE_H
|
||||||
|
|
||||||
#include "ServerFont.h"
|
#include "ServerFont.h"
|
||||||
|
|||||||
Reference in New Issue
Block a user