* style and family IDs are no longer just the index in their parent's lists (as

they can disappear and IDs should stay persistent at least as long as the
  system runs).
* destroying a FontStyle discards its FT_Face again.
* the font style and family names are now truncated to the appropriate length,
  so that they can always be used via the Be API.
* (char *) == (char *) hardly compares the string (but was probably introduced
  by me when I stopped FontFamily from accessing FontStyle privates
* removed FontServer::SaveList() - made no particular sense to me.
* removed superfluous "inline" keyword in the FontStyle definition.
* more cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14619 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-11-01 17:49:01 +00:00
parent b8cde4497e
commit b4f34cfb95
5 changed files with 134 additions and 224 deletions
+37 -41
View File
@@ -84,85 +84,81 @@ typedef struct {
*/ */
class FontStyle : public SharedObject, public BLocker { class FontStyle : public SharedObject, public BLocker {
public: public:
FontStyle(const char* filepath, FontStyle(const char* path, FT_Face face);
FT_Face face); virtual ~FontStyle();
virtual ~FontStyle();
/*! /*!
\fn bool FontStyle::IsFixedWidth(void) \fn bool FontStyle::IsFixedWidth(void)
\brief Determines whether the font's character width is fixed \brief Determines whether the font's character width is fixed
\return true if fixed, false if not \return true if fixed, false if not
*/ */
inline bool IsFixedWidth() const bool IsFixedWidth() const
{ return fFTFace->face_flags & FT_FACE_FLAG_FIXED_WIDTH; } { return fFTFace->face_flags & FT_FACE_FLAG_FIXED_WIDTH; }
/*! /*!
\fn bool FontStyle::IsScalable(void) \fn bool FontStyle::IsScalable(void)
\brief Determines whether the font can be scaled to any size \brief Determines whether the font can be scaled to any size
\return true if scalable, false if not \return true if scalable, false if not
*/ */
inline bool IsScalable() const bool IsScalable() const
{ return fFTFace->face_flags & FT_FACE_FLAG_SCALABLE; } { return fFTFace->face_flags & FT_FACE_FLAG_SCALABLE; }
/*! /*!
\fn bool FontStyle::HasKerning(void) \fn bool FontStyle::HasKerning(void)
\brief Determines whether the font has kerning information \brief Determines whether the font has kerning information
\return true if kerning info is available, false if not \return true if kerning info is available, false if not
*/ */
inline bool HasKerning() const bool HasKerning() const
{ return fFTFace->face_flags & FT_FACE_FLAG_KERNING; } { return fFTFace->face_flags & FT_FACE_FLAG_KERNING; }
/*! /*!
\fn bool FontStyle::HasTuned(void) \fn bool FontStyle::HasTuned(void)
\brief Determines whether the font contains strikes \brief Determines whether the font contains strikes
\return true if it has strikes included, false if not \return true if it has strikes included, false if not
*/ */
inline bool HasTuned() const bool HasTuned() const
{ return fFTFace->num_fixed_sizes > 0; } { return fFTFace->num_fixed_sizes > 0; }
/*! /*!
\fn bool FontStyle::TunedCount(void) \fn bool FontStyle::TunedCount(void)
\brief Returns the number of strikes the style contains \brief Returns the number of strikes the style contains
\return The number of strikes the style contains \return The number of strikes the style contains
*/ */
inline int32 TunedCount() const int32 TunedCount() const
{ return fFTFace->num_fixed_sizes; } { return fFTFace->num_fixed_sizes; }
/*! /*!
\fn bool FontStyle::GlyphCount(void) \fn bool FontStyle::GlyphCount(void)
\brief Returns the number of glyphs in the style \brief Returns the number of glyphs in the style
\return The number of glyphs the style contains \return The number of glyphs the style contains
*/ */
inline uint16 GlyphCount() const uint16 GlyphCount() const
{ return fFTFace->num_glyphs; } { return fFTFace->num_glyphs; }
/*! /*!
\fn bool FontStyle::CharMapCount(void) \fn bool FontStyle::CharMapCount(void)
\brief Returns the number of character maps the style contains \brief Returns the number of character maps the style contains
\return The number of character maps the style contains \return The number of character maps the style contains
*/ */
inline uint16 CharMapCount() const uint16 CharMapCount() const
{ return fFTFace->num_charmaps; } { return fFTFace->num_charmaps; }
const char* Name() const; const char* Name() const;
inline FontFamily* Family() const FontFamily* Family() const
{ return fFontFamily; } { return fFontFamily; }
inline uint16 ID() const uint16 ID() const
{ return fID; } { return fID; }
int32 Flags() const; int32 Flags() const;
inline uint16 Face() const uint16 Face() const
{ return fFace; } { return fFace; }
uint16 PreservedFace(uint16) const; uint16 PreservedFace(uint16) const;
const char* Path() const; const char* Path() const;
font_height GetHeight(const float& size) const; font_height GetHeight(const float& size) const;
font_direction Direction() const font_direction Direction() const
{ return B_FONT_LEFT_TO_RIGHT; } { return B_FONT_LEFT_TO_RIGHT; }
inline FT_Face GetFTFace() const FT_Face GetFTFace() const
{ return fFTFace; } { return fFTFace; }
// TODO: Re-enable when I understand how the FT2 Cache system changed from
// 2.1.4 to 2.1.8
// int16 ConvertToUnicode(uint16 c);
void AttachedToFamily(FontFamily* family); // TODO: Re-enable when I understand how the FT2 Cache system changed from
void DetachedFromFamily(); // 2.1.4 to 2.1.8
// int16 ConvertToUnicode(uint16 c);
private: private:
friend class FontFamily; friend class FontFamily;
@@ -198,8 +194,7 @@ class FontStyle : public SharedObject, public BLocker {
*/ */
class FontFamily : public SharedObject { class FontFamily : public SharedObject {
public: public:
FontFamily(const char* namestr, FontFamily(const char* name, uint16 id);
const uint16& index);
virtual ~FontFamily(); virtual ~FontFamily();
const char* Name() const; const char* Name() const;
@@ -220,10 +215,11 @@ class FontFamily : public SharedObject {
int32 CountStyles() const; int32 CountStyles() const;
FontStyle* StyleAt(int32 index) const; FontStyle* StyleAt(int32 index) const;
protected: private:
BString fName; BString fName;
BObjectList<FontStyle> fStyles; BObjectList<FontStyle> fStyles;
uint16 fID; uint16 fID;
uint16 fNextID;
int32 fFlags; int32 fFlags;
}; };
+5 -3
View File
@@ -20,6 +20,8 @@
#include FT_FREETYPE_H #include FT_FREETYPE_H
#include FT_CACHE_H #include FT_CACHE_H
class BPath;
class FontFamily; class FontFamily;
class FontStyle; class FontStyle;
class ServerFont; class ServerFont;
@@ -41,7 +43,6 @@ class FontServer : public BLocker {
void RemoveFamily(const char *family); void RemoveFamily(const char *family);
void ScanSystemFolders(); void ScanSystemFolders();
status_t ScanDirectory(const char *path); status_t ScanDirectory(const char *path);
void SaveList();
FontFamily* GetFamilyByIndex(int32 index) const; FontFamily* GetFamilyByIndex(int32 index) const;
FontFamily *GetFamily(uint16 familyID) const; FontFamily *GetFamily(uint16 familyID) const;
@@ -67,8 +68,8 @@ class FontServer : public BLocker {
*/ */
void FontsUpdated() { fNeedUpdate = false; } void FontsUpdated() { fNeedUpdate = false; }
protected: private:
uint16 TranslateStyleToFace(const char *name) const; void _AddFont(BPath &path);
FT_CharMap _GetSupportedCharmap(const FT_Face &face); FT_CharMap _GetSupportedCharmap(const FT_Face &face);
@@ -77,6 +78,7 @@ class FontServer : public BLocker {
BObjectList<FontFamily> fFamilies; BObjectList<FontFamily> fFamilies;
ServerFont *fPlain, *fBold, *fFixed; ServerFont *fPlain, *fBold, *fFixed;
bool fNeedUpdate; bool fNeedUpdate;
int32 fNextID;
}; };
extern FTC_Manager ftmanager; extern FTC_Manager ftmanager;
-1
View File
@@ -101,7 +101,6 @@ AppServer::AppServer()
gFontServer = new FontServer; gFontServer = new FontServer;
gFontServer->Lock(); gFontServer->Lock();
gFontServer->ScanSystemFolders(); gFontServer->ScanSystemFolders();
gFontServer->SaveList();
if (!gFontServer->SetSystemPlain(DEFAULT_PLAIN_FONT_FAMILY, if (!gFontServer->SetSystemPlain(DEFAULT_PLAIN_FONT_FAMILY,
DEFAULT_PLAIN_FONT_STYLE, DEFAULT_PLAIN_FONT_STYLE,
+44 -59
View File
@@ -1,50 +1,43 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2001-2002, Haiku, Inc. * Copyright 2001-2005, Haiku.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * DarkWyrm <[email protected]>
// the rights to use, copy, modify, merge, publish, distribute, sublicense, * Axel Dörfler, [email protected]
// and/or sell copies of the Software, and to permit persons to whom the */
// Software is furnished to do so, subject to the following conditions:
// /** Classes to represent font styles and families */
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: FontFamily.cpp
// Author: DarkWyrm <[email protected]>
// Description: classes to represent font styles and families
//
//------------------------------------------------------------------------------
#include "FontFamily.h" #include "FontFamily.h"
#include "ServerFont.h" #include "ServerFont.h"
#include FT_CACHE_H #include FT_CACHE_H
const int32 kInvalidFamilyFlags = -1;
FTC_Manager ftmanager; FTC_Manager ftmanager;
/*! /*!
\brief Constructor \brief Constructor
\param filepath path to a font file \param filepath path to a font file
\param face FreeType handle for the font file after it is loaded - it will be kept open until the FontStyle is destroied \param face FreeType handle for the font file after it is loaded - it will be kept open until the FontStyle is destroied
*/ */
FontStyle::FontStyle(const char *filepath, FT_Face face) FontStyle::FontStyle(const char *path, FT_Face face)
: :
fFTFace(face), fFTFace(face),
fFontFamily(NULL), fFontFamily(NULL),
fName(face->style_name), fName(face->style_name),
fPath(filepath), fPath(path),
fBounds(0, 0, 0, 0), fBounds(0, 0, 0, 0),
fID(0), fID(0),
fFace(_TranslateStyleToFace(face->style_name)) fFace(_TranslateStyleToFace(face->style_name))
{ {
fName.Truncate(B_FONT_STYLE_LENGTH);
// make sure this style can be found using the Be API
// cachedface = new CachedFaceRec; // cachedface = new CachedFaceRec;
// cachedface->file_path = filepath; // cachedface->file_path = filepath;
@@ -71,8 +64,7 @@ FontStyle::~FontStyle()
{ {
// TODO: what was the purpose of this? // TODO: what was the purpose of this?
// delete cachedface; // delete cachedface;
// TODO: figure out if it is safe to call this: FT_Done_Face(fFTFace);
// FT_Done_Face(fFTFace);
} }
@@ -200,13 +192,15 @@ FontStyle::_TranslateStyleToFace(const char *name) const
\brief Constructor \brief Constructor
\param namestr Name of the family \param namestr Name of the family
*/ */
FontFamily::FontFamily(const char *name, const uint16 &index) FontFamily::FontFamily(const char *name, uint16 id)
:
fName(name),
fID(id),
fNextID(0),
fFlags(kInvalidFamilyFlags)
{ {
fName = name; fName.Truncate(B_FONT_FAMILY_LENGTH);
fID = index; // make sure this family can be found using the Be API
// will stay uninitialized until needed
fFlags = -1;
} }
/*! /*!
@@ -220,7 +214,7 @@ FontFamily::~FontFamily()
{ {
int32 count = fStyles.CountItems(); int32 count = fStyles.CountItems();
for (int32 i = 0; i < count; i++) for (int32 i = 0; i < count; i++)
delete (FontStyle*)fStyles.ItemAt(i); delete fStyles.ItemAt(i);
} }
@@ -245,30 +239,22 @@ FontFamily::AddStyle(FontStyle *style)
if (!style) if (!style)
return false; return false;
FontStyle *item;
// Don't add if it already is in the family. // Don't add if it already is in the family.
int32 count = fStyles.CountItems(); int32 count = fStyles.CountItems();
for (int32 i = 0; i < count; i++) { for (int32 i = 0; i < count; i++) {
item = (FontStyle*)fStyles.ItemAt(i); FontStyle *item = fStyles.ItemAt(i);
if (item->Name() == style->Name()) if (!strcmp(item->Name(), style->Name()))
return false; return false;
} }
style->_SetFontFamily(this); style->_SetFontFamily(this);
style->_SetID(fNextID++);
if (fStyles.CountItems() > 0) {
item = (FontStyle*)fStyles.ItemAt(fStyles.CountItems() - 1);
style->_SetID(item->ID() + 1);
} else {
style->_SetID(0);
}
fStyles.AddItem(style); fStyles.AddItem(style);
AddDependent(); AddDependent();
// force a refresh if a request for font flags is needed // force a refresh if a request for font flags is needed
fFlags = -1; fFlags = kInvalidFamilyFlags;
return true; return true;
} }
@@ -291,7 +277,7 @@ FontFamily::RemoveStyle(const char* styleName)
RemoveDependent(); RemoveDependent();
// force a refresh if a request for font flags is needed // force a refresh if a request for font flags is needed
fFlags = -1; fFlags = kInvalidFamilyFlags;
} }
@@ -306,7 +292,7 @@ FontFamily::RemoveStyle(FontStyle* style)
RemoveDependent(); RemoveDependent();
// force a refresh if a request for font flags is needed // force a refresh if a request for font flags is needed
fFlags = -1; fFlags = kInvalidFamilyFlags;
} }
} }
@@ -403,17 +389,16 @@ FontFamily::GetStyleMatchingFace(uint16 face) const
int32 int32
FontFamily::Flags() FontFamily::Flags()
{ {
if (fFlags == -1) { if (fFlags == kInvalidFamilyFlags) {
fFlags = 0; fFlags = 0;
for (int32 i = 0; i < fStyles.CountItems(); i++) { for (int32 i = 0; i < fStyles.CountItems(); i++) {
FontStyle* style = (FontStyle*)fStyles.ItemAt(i); FontStyle* style = fStyles.ItemAt(i);
if (style) {
if (style->IsFixedWidth()) if (style->IsFixedWidth())
fFlags |= B_IS_FIXED; fFlags |= B_IS_FIXED;
if (style->TunedCount() > 0) if (style->TunedCount() > 0)
fFlags |= B_HAS_TUNED_FONT; fFlags |= B_HAS_TUNED_FONT;
}
} }
} }
+48 -120
View File
@@ -21,6 +21,8 @@
#include <ServerFont.h> #include <ServerFont.h>
#include "ServerConfig.h" #include "ServerConfig.h"
#include <new>
extern FTC_Manager ftmanager; extern FTC_Manager ftmanager;
FT_Library ftlib; FT_Library ftlib;
@@ -52,7 +54,8 @@ FontServer::FontServer()
fFamilies(20), fFamilies(20),
fPlain(NULL), fPlain(NULL),
fBold(NULL), fBold(NULL),
fFixed(NULL) fFixed(NULL),
fNextID(0)
{ {
fInitStatus = FT_Init_FreeType(&ftlib) == 0 ? B_OK : B_ERROR; fInitStatus = FT_Init_FreeType(&ftlib) == 0 ? B_OK : B_ERROR;
@@ -132,19 +135,50 @@ FontServer::ScanSystemFolders(void)
#endif #endif
} }
/*!
\brief Adds the FontFamily/FontStyle that is represented by this path.
*/
void
FontServer::_AddFont(BPath &path)
{
FT_Face face;
FT_Error error = FT_New_Face(ftlib, path.Path(), 0, &face);
if (error != 0)
return;
FontFamily *family = GetFamily(face->family_name);
if (family != NULL && 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;
}
if (family == NULL) {
family = new (nothrow) FontFamily(face->family_name, fNextID++);
if (family == NULL
|| !fFamilies.AddItem(family)) {
delete family;
FT_Done_Face(face);
return;
}
}
#ifdef PRINT_FONT_LIST
printf("\tFont Style: %s, %s\n", face->family_name, face->style_name);
#endif
// the FontStyle takes over ownership of the FT_Face object
FontStyle *style = new FontStyle(path.Path(), face);
if (!family->AddStyle(style))
delete style;
}
/*! /*!
\brief Scan a folder for all valid fonts \brief Scan a folder for all valid fonts
\param fontspath Path of the folder to scan. \param directoryPath Path of the folder to scan.
\return
- \c B_OK Success
- \c B_NAME_TOO_LONG The path specified is too long
- \c B_ENTRY_NOT_FOUND The path does not exist
- \c B_LINK_LIMIT A cyclic loop was detected in the file system
- \c B_BAD_VALUE Invalid input specified
- \c B_NO_MEMORY Insufficient memory to open the folder for reading
- \c B_BUSY A busy node could not be accessed
- \c B_FILE_ERROR An invalid file prevented the operation.
- \c B_NO_MORE_FDS All file descriptors are in use (too many open files).
*/ */
status_t status_t
FontServer::ScanDirectory(const char *directoryPath) FontServer::ScanDirectory(const char *directoryPath)
@@ -165,10 +199,6 @@ FontServer::ScanDirectory(const char *directoryPath)
if (status < B_OK) if (status < B_OK)
continue; continue;
FT_Face face;
FT_Error error = FT_New_Face(ftlib, path.Path(), 0, &face);
if (error != 0)
continue;
// TODO: Commenting this out makes my "Unicode glyph lookup" // TODO: Commenting this out makes my "Unicode glyph lookup"
// work with our default fonts. The real fix is to select the // work with our default fonts. The real fix is to select the
@@ -186,34 +216,8 @@ FontServer::ScanDirectory(const char *directoryPath)
face->charmap = charmap; face->charmap = charmap;
#endif #endif
FontFamily *family = GetFamily(face->family_name); _AddFont(path);
if (family == NULL) { // takes over ownership of the FT_Face object
#ifdef PRINT_FONT_LIST
printf("Font Family: %s\n", face->family_name);
#endif
family = new FontFamily(face->family_name, fFamilies.CountItems());
fFamilies.AddItem(family);
} else {
// prevent adding the same style twice
// (this indicates a problem with the installed fonts maybe?)
if (family->HasStyle(face->style_name)) {
FT_Done_Face(face);
continue;
}
}
#ifdef PRINT_FONT_LIST
printf("\tFont Style: %s\n", face->style_name);
#endif
FontStyle *style = new FontStyle(path.Path(), face);
if (!family->AddStyle(style))
delete style;
// FT_Face is kept open in FontStyle and will be unset in the
// FontStyle destructor
// TODO: nope, it is not (yet)
} }
fNeedUpdate = true; fNeedUpdate = true;
@@ -261,82 +265,6 @@ FontServer::_GetSupportedCharmap(const FT_Face& face)
} }
/*!
\brief This saves all family names and styles to the file specified in
ServerConfig.h as SERVER_FONT_LIST as a flattened BMessage.
This operation is not done very often because the access to disk adds a significant
performance hit.
The format for storage consists of two things: an array of strings with the name 'family'
and a number of small string arrays which have the name of the font family. These are
the style lists.
Additionally, any fonts which have bitmap strikes contained in them or any fonts which
are fixed-width are named in the arrays 'tuned' and 'fixed'.
*/
void
FontServer::SaveList(void)
{
/* int32 famcount=0, stycount=0,i=0,j=0;
FontFamily *fam;
FontStyle *sty;
BMessage fontmsg, familymsg('FONT');
BString famname, styname, extraname;
bool fixed,tuned;
famcount=families->CountItems();
for(i=0; i<famcount; i++)
{
fam=(FontFamily*)families->ItemAt(i);
fixed=false;
tuned=false;
if(!fam)
continue;
famname=fam->Name();
// Add the family to the message
familymsg.AddString("name",famname);
stycount=fam->CountStyles();
for(j=0;j<stycount;j++)
{
styname.SetTo(fam->GetStyle(j));
if(styname.CountChars()>0)
{
// Add to list
familymsg.AddString("styles", styname);
// Check to see if it has prerendered strikes (has "tuned" fonts)
sty=fam->GetStyle(styname.String());
if(!sty)
continue;
if(sty->HasTuned() && sty->IsScalable())
tuned=true;
// Check to see if it is fixed-width
if(sty->IsFixedWidth())
fixed=true;
}
}
if(tuned)
familymsg.AddBool("tuned",true);
if(fixed)
familymsg.AddBool("fixed",true);
fontmsg.AddMessage("family",&familymsg);
familymsg.MakeEmpty();
}
BFile file(SERVER_FONT_LIST,B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE);
if(file.InitCheck()==B_OK)
fontmsg.Flatten(&file);
*/
}
FontFamily* FontFamily*
FontServer::GetFamilyByIndex(int32 index) const FontServer::GetFamilyByIndex(int32 index) const
{ {